Skip to main content
A manifest is the unit of work for every command in this group. It names one blob and one revision, lists everything that belongs on that revision, and binds each code component to a place in your repository. There is no per-definition manifest and no default path — -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

Four fields sit at the top of every manifest the CLI reads, whatever blob domain it belongs to. The base is parsed and validated by itself, before the body is looked at; type is what selects the body.
All four must be non-empty strings. That is the whole base — the scheduler group’s manifest carries exactly these four fields and then its own body, and a future blob domain does the same. Nothing on the shared side changes when one arrives.

blob

acme-corp/checkout qualifies the org in the file. A bare checkout does not, and inherits the org from the global --org option or the BLOBHUB_ORG environment variable — which org a checkout belongs to is a property of the checkout, not of the key being used to reach it, so a profile is deliberately not a source for it. With a bare name and neither supplied, the manifest is MANIFEST_INVALID and the message names all three ways to fix it, since two of them are not in the file in front of you. An org-scoped API key checks its target as a raw string against the org UUID. Addressing that org by its alias yields a confusing 403 on every call, so under an org-scoped key qualify the manifest — or --org — with the UUID. The blob’s shape is confirmed before any engine call: a workflow manifest pointed at a blob of another domain stops with BLOB_NOT_WORKFLOW rather than an opaque 500 one round trip later.

revision

latest resolves through the blob’s latest_revision_id at the moment the command runs. A pinned UUID names one revision for as long as the manifest says so. Which revisions a command will accept depends on the direction it moves data: The CLI fetches the revision and applies this itself, so a refusal names the phase and points at diff. The platform’s own rejection is a bare 400 that does not mention the revision at all. build is exempt from all of it — it never resolves a revision.

Every path anchors to the manifest’s own directory

source, code.base_path and value.source all resolve against the directory holding the manifest file, never against the current working directory and never against each other. A manifest is revision-scoped, and its definitions are typically scattered across several directories, so a source-relative anchor would make the meaning of a ../.. depend on which subdirectory a given definition happened to sit in. entry_point is the one exception: it resolves against base_path, because it names a module inside the Python package base_path roots rather than a file in the project. Paths are collapsed lexically, so .. segments work and are resolved without touching the filesystem.

The workflow_blob_deployment body

One key: definitions, a list with at least one entry. An empty or absent list is MANIFEST_INVALID. 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.

category

Inferred from the source document’s own type: workflow_definition gives workflow, playground_definition gives playground. One function owns this rule for every command in the group, build included, so no two commands can disagree about what an entry is.
  • Omitted, document present, type recognized — the inferred category wins.
  • Omitted, document present, type unrecognizedDEFINITION_CATEGORY_UNKNOWN. Declare category.
  • Omitted, document absent (before a first pull) — defaults to workflow.
  • Declared, type unrecognized — the declared category wins. This is what declaring it is for: a type that names no native category contradicts nothing.
  • Declared, and it contradicts the documentDEFINITION_CATEGORY_UNKNOWN, naming both.
That last case is an error rather than a warning because nothing server-side catches it. A workflow upload validates nothing at all, so a playground document declared as a workflow uploads cleanly into the workflow definition’s id and corrupts it silently. Category is not decoration: a definition is identified by the (category, alias) pair, so one alias may legitimately name a workflow definition and a playground definition on the same revision.

components[]

Each binding says which component it addresses, and what to put in it. code and value are mutually exclusive; declaring both is MANIFEST_INVALID. A binding with neither resolves the component and writes nothing, which makes it a no-op that can still fail with COMPONENT_NOT_FOUND. A code binding is what build and deploy act on, and the only thing the compiler is ever pointed at. The bound component’s language port must be exactly python; anything else, including no language port at all, is LANGUAGE_NOT_PYTHON.

A worked example

A revision holding two definitions: a workflow whose logic.code component (id: c1) is compiled from pkg/ and whose pricing table is loaded from a JSON file, plus a playground with nothing bound into it.
Both files load to the same manifest. The entry point compiled here is pkg/entry.pyentry_point is relative to base_path, while base_path itself, source and value.source are all relative to the manifest. The playground entry declares no category, so it is inferred from its document’s type. It declares no components either: playground definitions are moved verbatim by pull and push, and nothing compiles into them.

Errors

Every code above, with its remediation, is in Error codes.

See also

  • Workflow overview — the shape of a deployable project and the ten commands that move it.
  • Compiler — what a code binding produces, and every check it runs first.
  • Sandbox — what the compiled code executes against.
  • Concepts — why a manifest is revision-scoped, and why category participates in identity.
  • Workflow definition format — the document a source points at.