-f/--file is required everywhere, and the file it names is loaded before anything else happens.
The file is parsed by extension: .yaml, .yml and .json all work, and the same manifest written in YAML or in
JSON loads identically. An unsupported extension is FORMAT_UNSUPPORTED; a file that does not parse is
FORMAT_PARSE_ERROR.
The shared base
scheduler_blob_deployment is the second manifest type over the shared base the
workflow manifest introduces. The base is parsed and validated by
itself, before the body is looked at, and type is what selects the body — so these four fields mean here exactly
what they mean there.
The blob’s shape is confirmed before any engine call: a
scheduler manifest pointed at a workflow blob stops with
BLOB_NOT_WORKFLOW — one shared resolver raises that code for every group, and its message names both the shape
found and the shape expected.
A scheduler blob is created in phase managed and holds a single revision, always, so revision: latest is
the normal value and names the one revision there is. Pinning a UUID is legal and does exactly what it does in the
workflow group.
The scheduler_blob_deployment body
One key: schedules, a list.
Unlike the workflow body’s definitions, an empty list is valid — a revision holding no schedules is an
ordinary state, and an empty schedules: [] is precisely the document pull writes for one. A missing key is
still MANIFEST_INVALID: absent is a manifest that says nothing about schedules, empty is one that says there are
none.
The CLI carries every time and date field through as an opaque string and checks none of their contents, so the
naive/UTC split above is the platform’s rule, enforced where the schedule is written rather than where it is
authored.
Unlisted keys are ignored rather than rejected, so a typo’d field name is silently inert. There is no schema
beyond what is described here.
repeat decides which timing field exists
repeat gives exactly one of cron_expression and invocation_time meaning, and the manifest must carry that
one and only that one. A recurring_cron entry without a cron_expression, or a one_time entry without an
invocation_time, is MANIFEST_INVALID. So is an entry carrying both.
Refusing both is worth the extra rule. The likeliest way to arrive there is the half-finished edit that flips
repeat and leaves the old kind’s field behind — and the field left behind can never take effect, never be
reported as differing, and can never be removed from a deployed schedule either: update_schedule sets only the
keys it is sent and rejects a null, so a record flipped from recurring_cron to one_time keeps its stale
cron_expression for good. Only the field repeat gives meaning to is compared, by diff and deploy alike.
The target block
target names a workflow blob, not the scheduler blob the manifest is about. blob, revision, session
and workflow are required; type, input_data and description are not.
input_data is the one field nothing checks until the schedule fires. The scheduler’s own schema types it as a
bare array, so create_schedule accepts any list at all; the item shape —
{"alias": "<component alias>", "value": {"type": …}}, documented under
Create Execution — is enforced by create_execution at fire
time, where a violation surfaces as an invocation_error on the schedule’s execution history rather than as a
failed deploy.
Four constraints, checked before anything is written
These four are answered offline, at load time, before a single schedule is created or updated. They are checked locally rather than left to the server for one reason:deploy writes entries in order, so a manifest whose
second entry breaks a rule the platform enforces would deploy the first and then fail — leaving a half-deployed
set that is already firing on its cron.
alias is required on every entry, which the platform does not require of a schedule — it is the manifest’s
identity for one, and what makes a second deploy an update rather than a duplicate.
cron_expression and timezone are the one class of failure the CLI cannot catch beforehand. Neither is
constrained by any schema, and the CLI passes both through as opaque strings. They are validated when the schedule
is written:
- The platform itself answers the two cron mistakes that are common and badly reported downstream — an expression
that is not exactly six space-separated fields, and one where day-of-month and day-of-week are not exactly one
?between them. Both come back asinvalid_cron_expression. The plausible-looking0 9 * * MON-FRI *is the second of those;0 9 ? * MON-FRI *is the working form. - Everything else — ranges, steps, month and day names, out-of-range values, and the timezone, which is handed
straight to the scheduling service as its
ScheduleExpressionTimezone— is the scheduling service’s own rejection, surfaced with its message.
A worked example
A scheduler blobacme-corp/checkout-ops carrying two schedules against the workflow blob acme-corp/checkout:
a recurring one that runs every morning in New York time against a session it shares with every other run, and a
one-time launch pinned to a specific revision, with input data and an execution description.
blob: checkout is bare and inherits acme-corp from the
manifest’s own blob; the second qualifies the same org explicitly, which is equivalent. The first entry omits
type in its target, which is the same as declaring workflow.
The second entry’s pinned target.revision is worth one note. latest and a pinned UUID both reach the platform
as a resolved revision id, so nothing in a stored schedule records which of the two the manifest wrote. pull
reads that back from the manifest entry it is refreshing, matched by alias — so a pin survives a pull instead of
being flattened to latest the moment it happens to name the leading revision. A schedule the manifest never
carried has no such record: it comes back as latest when its target revision still leads the blob, and as a
literal UUID when it does not.
Errors
Every code above, with its remediation, is in Error codes.
See also
- Scheduler overview — the two blobs one deploy touches, and the four commands that manage them.
- Workflow manifest — the same shared base, with the
workflow_blob_deploymentbody over it. - Scheduler blob type — cron syntax, timezones, date windowing, alias grammar and schedule states, as the platform defines them.
- Concepts — why a manifest is revision-scoped, and why drift in this group is not inert.

