> ## 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 scheduler ls

> List the revision’s schedules, marking which the manifest covers and which are firing unclaimed

`ls` answers one question: what is actually firing on this revision, and how much of it does my manifest know
about? It lists every schedule the revision holds and marks the ones the manifest covers.

It is the read-only view of drift. Every other command in this group reports drift as a summary line; `ls` shows
it row by row, with the id you would need to go find the schedule in the web UI.

## Synopsis

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

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

That is the whole surface. There is no per-schedule filter — narrowing a listing to the subset you already
declared would defeat the point of listing it — and no `--dry-run`, because nothing is written locally or
remotely.

## What it does

1. Loads the manifest and resolves the scheduler blob and revision. This is a read, so a `commit`-phase revision
   lists fine.
2. Pages `list_schedules` **to completion**, following the platform's cursor until it stops returning one. Unlike
   the definition listing behind [`blobhub workflow ls`](/cli/workflow/commands/ls), this one really does page,
   so there is no truncation advisory here and no silently dropped rows.
3. Matches each schedule's alias against the manifest's entries.
4. Prints one row per **remote** schedule, sorted by alias, with aliasless schedules last:

```text theme={null}
  ALIAS                          ID                                     REPEAT          ENABLED  STATE      WORKFLOW
* daily_checkout_report          7f04b1ff-5df0-4467-957b-2e7bf13f77b0   recurring_cron  True     active     checkout_flow
  weekly_cleanup                 4bd5edf4-e130-4667-b0eb-fe9e840b62a8   recurring_cron  True     active     checkout_flow
  --                             419365d8-a798-49dd-ad29-5f97a9c1b901   one_time        True     completed  checkout_flow
```

`*` marks a schedule the manifest covers. An unmarked row is drift: it exists on the revision, no manifest entry
claims it, and — unlike a drifted workflow definition, which sits inert — **it is still firing on its cron**.
Nothing in this group removes one. `blobhub scheduler prune` is the removal path the drift messages elsewhere in
this group name, and it is not yet available — so removing a schedule today means the web UI or a
`delete_schedule` call.

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/scheduler/commands/diff) is what reports that direction.

`STATE` is the platform's own schedule state, not something the CLI computes; `ENABLED` is the manifest-settable
flag. The two are independent, and a schedule can be `enabled` and yet in a state where it will never fire again.
[Schedule states](/blob-types/scheduler/overview#schedule-states) defines the set.

Under `--json` the payload carries `schedules` — each row with `alias`, `id`, `repeat`, `enabled`, `state`,
`workflow_alias` and `in_manifest` — alongside `drift` and the envelope's `schema_version`, in the same shape
every other command in this CLI reports it. The rendered `drift:` line every other command prints is suppressed
here, because an unmarked row already says it; the key is still present so a script can read it uniformly across
commands.

## A schedule with no alias

`--` in the alias column is not a rendering placeholder for something the CLI failed to read. It means the
platform stored no alias at all.

**A schedule's `alias` is optional platform-side.** `create_schedule` writes the attribute only when one was
supplied, and the web UI's create form offers a blank field as a valid choice — so a schedule created in the
browser has no alias unless someone typed one. Its record simply has no `alias` key.

That schedule is **unmanageable declaratively**. Alias is a manifest entry's identity, so nothing in a manifest
can address one that has none: [`deploy`](/cli/scheduler/commands/deploy) can neither update it nor recognise it,
and [`pull`](/cli/scheduler/commands/pull) cannot write it out. It is listed here anyway, by id, precisely because
it is still firing — a schedule you cannot see is worse than one you cannot manage, and the id in that row is the
only handle you have for going and removing it.

In `--json` its `alias` stays `null` rather than being backfilled with its id. That matters for anything reading
the payload: a consumer that could not tell an aliasless schedule from one named after its own id would write a
manifest entry for it, and the next `deploy` would create a **second** schedule beside the one still firing.

There is one way out, and it is not a CLI command. The platform's
[Update Schedule](/blob-types/scheduler/operations/update-schedule) operation takes an optional `alias`, so an
existing schedule can be given one in place — after which it appears in this listing by name and the manifest can
adopt it like any other. No `scheduler` command will do that for you: `deploy` matches schedules by alias and
never sends one on an update, so it has no way to name a schedule that has no name yet.

## What `ls` does not check

`ls` reads the scheduler blob and nothing else. It never resolves a schedule's target, so the `WORKFLOW` column
is the alias the platform has stored, reported verbatim — not a claim that the alias still resolves to anything.

That distinction has teeth, because `workflow_alias` is re-resolved every time the schedule fires. A workflow
definition renamed or deleted on the target revision leaves its schedule listed here, `enabled`, `active`, and
firing into nothing. [`diff`](/cli/scheduler/commands/diff) is the read-only command that checks the alias
against the target revision; `ls` is the faster one that does not.

## Errors

| Code                                                                                               | When                                                                                                                                                                                                                                                                                                           |
| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MANIFEST_NOT_FOUND`, `MANIFEST_INVALID`, `MANIFEST_TYPE_MISMATCH`, `MANIFEST_VERSION_UNSUPPORTED` | The manifest is absent or unusable. It is loaded and fully validated before any call, even though `ls` only uses it for the coverage markers.                                                                                                                                                                  |
| `SCHEDULE_ALIAS_REQUIRED`, `SCHEDULE_ALIAS_INVALID`                                                | A manifest entry has no `alias`, or one that fails `^[a-z0-9_-]{6,42}$`. Checked at load, so it stops `ls` too.                                                                                                                                                                                                |
| `BLOB_NOT_ACCESSIBLE`, `BLOB_NOT_WORKFLOW`, `REVISION_NOT_ACCESSIBLE`, `REVISION_NOT_WRITABLE`     | The scheduler blob cannot be resolved, is a blob of another domain, or its revision is unreachable or 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`                                                         | The manifest has an unsupported extension, or does not parse.                                                                                                                                                                                                                                                  |
| `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.                                                                                                                                                                                                                                                                               |

A schedule 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 scheduler diff`](/cli/scheduler/commands/diff) — the other direction: what the manifest has that the
  revision does not, and how the two differ where they overlap.
* [`blobhub scheduler pull`](/cli/scheduler/commands/pull) — how an unmarked aliased row gets into your manifest.
* [Scheduler manifest](/cli/scheduler/manifest) — the alias grammar behind the load-time codes above.
* [Scheduler blob type](/blob-types/scheduler/overview) — schedule states, cron syntax and what the platform
  records for every fire.
