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
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
- Loads the manifest and resolves the scheduler blob and revision. This is a read, so a
commit-phase revision lists fine. - Pages
list_schedulesto completion, following the platform’s cursor until it stops returning one. Unlike the definition listing behindblobhub workflow ls, this one really does page, so there is no truncation advisory here and no silently dropped rows. - Matches each schedule’s alias against the manifest’s entries.
- Prints one row per remote schedule, sorted by alias, with aliasless schedules last:
* 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 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 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 can neither update it nor recognise it,
and 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 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 is the read-only command that checks the alias
against the target revision; ls is the faster one that does not.
Errors
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.
See also
blobhub scheduler diff— the other direction: what the manifest has that the revision does not, and how the two differ where they overlap.blobhub scheduler pull— how an unmarked aliased row gets into your manifest.- Scheduler manifest — the alias grammar behind the load-time codes above.
- Scheduler blob type — schedule states, cron syntax and what the platform records for every fire.

