ls answers one question: what is actually on this revision, and how much of it does my manifest know about?
It lists every definition in both categories and marks the ones the manifest covers.
It is the read-only view of drift. Where every other command mentions drift in a summary line, ls shows it row
by row, with the id you would need to go look at a definition in the web UI.
Synopsis
No
--definition here. ls and prune are the two commands in this group
that do not take one, for the same reason: both work on the whole revision against the whole manifest, and
narrowing either of them to a subset you already declared would defeat the point. And there is no --dry-run on
ls: nothing is written, uploaded, or deleted.
What it does
- Resolves the blob and revision. This is a read, so a
commit-phase revision lists fine. - Lists the revision’s
workflowandplaygrounddefinitions — two calls, since the platform has no combined listing. - Resolves each manifest entry’s category from its local document, the same rule every other command uses.
- Prints one row per remote definition, sorted by category then alias:
* marks a definition the manifest covers. An unmarked row is drift: it exists on the revision, no manifest
entry claims it, and no command in this group will touch it except
prune.
The listing is of the revision, not the manifest. A manifest entry that has not been deployed yet does not
appear here at all — diff is what reports that direction.
Coverage is matched on the (category, alias) pair, not on the alias alone. An alias that names both a workflow
and a playground definition is two rows, and one of them can be covered while the other drifts.
Under --json the payload carries definitions — each row with category, alias, id and in_manifest —
alongside drift and the envelope’s schema_version, in the same shape every other command reports it. The
rendered drift: line is suppressed here, because the table already flags every drifted row with its own marker
and restating it below would say the same thing twice; the key is still present so a script can read it uniformly
across commands.
DEFINITION_LIST_TRUNCATED
This is where the advisory most often shows up, and it is worth understanding rather than filtering out:
- It is an advisory, not an error. It goes to stderr and the exit code stays
0, because a truncated listing is still a correct listing of what came back. - It needs an
admin-scoped key. The maximum is a blob limit, and limits requireadminto read. With aread/writekey the limits call is refused, the check is skipped, and you get no warning — the truncation can still be happening. - It never fires for playground definitions. The check looks up a per-category limit, and the platform
defines
workflow_definitions_per_revisiononly; there is no playground equivalent for it to compare against. A revision carrying a very large number of playground definitions is the one case where a truncated listing passes in silence. - It is invisible from automation. Like every advisory it is suppressed when stderr is not a TTY, absent from
the
--jsonpayload, and restored by no flag — so a CI log will not carry it. Runlson a terminal when you need to know.
prune’s, which is computed from the same listing.
Errors
A definition on the revision that the manifest does not cover is never an error here. Drift is a finding, not
a failure, and
ls exits 0 however much of it there is.
Every code above, with its remediation, is in Error codes.
See also
blobhub workflow prune— the only command that removes what this one marks.blobhub workflow diff— the other direction: what the manifest has that the revision does not, and how the two differ where they overlap.blobhub blob revisions— the revisions themselves, one level up.blobhub blob limits— the configured maximum behind the truncation advisory, and the key that can read it.

