> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blobhub.io/llms.txt
> Use this file to discover all available pages before exploring further.

# blobhub workflow ls

> List the revision’s definitions, marking which ones the manifest covers

`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

```bash theme={null}
blobhub workflow ls -f <manifest>
```

| Flag           | Default  | Description                    |
| -------------- | -------- | ------------------------------ |
| `--file`, `-f` | required | Path to the workflow manifest. |

**No `--definition` here.** `ls` and [`prune`](/cli/workflow/commands/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

1. Resolves the blob and revision. This is a read, so a `commit`-phase revision lists fine.
2. Lists the revision's `workflow` and `playground` definitions — two calls, since the platform has no combined
   listing.
3. Resolves each manifest entry's category from its local document, the same rule every other command uses.
4. Prints one row per **remote** definition, sorted by category then alias:

```text theme={null}
  CATEGORY   ALIAS                          ID
* playground checkout_lab                   9b30f1c2-...
* workflow   checkout_flow                  4c1fa7d8-...
  workflow   legacy_flow                    77a2be05-...
```

`*` 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`](/cli/workflow/commands/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`](/cli/workflow/commands/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:

```text theme={null}
warning: DEFINITION_LIST_TRUNCATED: list_definitions returned 50 workflow definition(s), matching the revision's configured maximum of 50 -- the platform cannot page this listing, so the result may be missing definitions it silently dropped
```

**The platform's definition listing has no pagination at all** — no cursor, no limit, no continuation token. A
revision with enough definitions to exceed one storage page is silently truncated, and nothing in the API says
so. This CLI cannot fix that; what it can do is notice, by reading the revision's configured maximum and warning
when the count it got back has reached it.

Four consequences:

* **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 require `admin` to read. With a
  `read`/`write` key 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_revision` only; 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 `--json` payload, and restored by no flag — so a CI log will not carry it. Run `ls` on a terminal when you
  need to know.

When it does fire, treat every drift verdict on the revision as provisional — including
[`prune`](/cli/workflow/commands/prune)'s, which is computed from the same listing.

## Errors

| Code                                                                                               | When                                                                                                                                                                                                                                                     |
| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MANIFEST_NOT_FOUND`, `MANIFEST_INVALID`, `MANIFEST_TYPE_MISMATCH`, `MANIFEST_VERSION_UNSUPPORTED` | The manifest is absent or unusable.                                                                                                                                                                                                                      |
| `DEFINITION_ALIAS_INVALID`, `DEFINITION_CATEGORY_UNKNOWN`                                          | An entry's alias fails the pattern; or its category cannot be inferred and none is declared, or the declared one contradicts the document.                                                                                                               |
| `BLOB_NOT_ACCESSIBLE`, `BLOB_NOT_WORKFLOW`, `REVISION_NOT_ACCESSIBLE`, `REVISION_NOT_WRITABLE`     | The target cannot be resolved, or its status is not `ready`. This is a read, so the phase may be `draft`, `commit` or `managed` — anything else raises `REVISION_NOT_WRITABLE`, which the shared resolver raises on the read path too, despite the name. |
| `FORMAT_UNSUPPORTED`, `FORMAT_PARSE_ERROR`                                                         | A local `source` file has an unsupported extension, or does not parse — it is read to resolve the entry's category.                                                                                                                                      |
| `CREDENTIALS_NOT_FOUND`, `PROFILE_NOT_FOUND`, `INSECURE_CREDENTIALS_PERMISSIONS`                   | No usable credential, or a credentials file the CLI refuses to read.                                                                                                                                                                                     |
| `API_RATE_LIMITED`, `API_TRANSIENT_ERROR`, `API_NETWORK_ERROR`                                     | A call failed after its retries.                                                                                                                                                                                                                         |
| `DEFINITION_LIST_TRUNCATED`                                                                        | Advisory, on stderr. The exit code stays `0`.                                                                                                                                                                                                            |

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](/cli/error-codes).

## See also

* [`blobhub workflow prune`](/cli/workflow/commands/prune) — the only command that removes what this one marks.
* [`blobhub workflow diff`](/cli/workflow/commands/diff) — the other direction: what the manifest has that the
  revision does not, and how the two differ where they overlap.
* [`blobhub blob revisions`](/cli/blob/revisions) — the revisions themselves, one level up.
* [`blobhub blob limits`](/cli/blob/limits) — the configured maximum behind the truncation advisory, and the key
  that can read it.
