> ## 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 push

> Upload each manifest definition verbatim, creating it first when its alias is absent

`push` uploads each definition file to the revision exactly as it stands on disk. No compiler runs, nothing is
skipped for being unchanged, and an alias the revision does not have yet is created on the way.

It is the write half of the `pull`/`push` pair, and it is rarely the command you want for code: a manifest that
binds a Python package expects [`build`](/cli/workflow/commands/build) to have run first, or
[`deploy`](/cli/workflow/commands/deploy) to do both. `push` is for a document you edited directly.

## Synopsis

```bash theme={null}
blobhub workflow push -f <manifest> [--definition <alias>] [--dry-run]
```

| Flag           | Default                          | Description                                 |
| -------------- | -------------------------------- | ------------------------------------------- |
| `--file`, `-f` | required                         | Path to the workflow manifest.              |
| `--definition` | every definition in the manifest | Limit to this alias. Repeatable.            |
| `--dry-run`    | off                              | Report the intended calls and perform none. |

## What it does

1. Loads the manifest and resolves its blob and revision. This is a write, so the revision must have status
   `ready` and phase `draft` or `managed`; `commit` is refused.
2. Lists the revision's definitions in both categories and matches the manifest against them.
3. For each entry, reads the `source` document — a missing file is `MANIFEST_INVALID`, not a silent skip — and
   uploads it. An alias absent from the revision is created first.
4. Prints drift, then one line per definition:

```text theme={null}
created workflow/checkout_flow
pushed workflow/checkout_flow
```

A newly created definition appears on both lines, because both calls happened. Under `--json` the payload
carries `created`, `uploaded`, `planned`, `dry_run` and `drift`, alongside the envelope's `schema_version`.

## Creating an absent alias takes two calls

`create_definition` writes an **empty stub** — an alias, a category, and for a playground its canonical `layout`
— and nothing else. `upload_definition` is then a full replace of that stub's document. The platform offers no
create-with-content call, so the sequence is two calls, in that order, and `push` performs both.

The gap between them is why a freshly created definition briefly exists with no content, and why an interrupted
`push` can leave a stub behind. Re-running `push` fixes it: the alias now exists, so the second run skips
straight to the upload.

For a playground, the `layout` handed to `create_definition` comes from the document being pushed. The platform
canonicalizes it at creation and compares every later upload against it, so the layout you create with is the
layout that definition keeps.

## Verbatim means unvalidated

`upload_definition` validates nothing. The workflow and playground upload schemas are placeholders that accept
any object, so a malformed document — or a playground document uploaded into a workflow definition — is accepted
without complaint and corrupts that definition silently.

Two things stand between you and that. The manifest's `category` rule catches the document/category mismatch
locally, because nothing server-side will. And [`check`](/cli/workflow/commands/check) is what tells you whether
what you uploaded is a workflow the platform can run — `push` never runs it, unlike `deploy`.

`push` also uploads **every** definition it resolves, changed or not. Only `deploy` compares against the remote
document first.

## `--dry-run`

Resolves everything and reports the intended calls without making them:

```text theme={null}
would create and upload workflow/checkout_flow
would upload playground/checkout_lab
```

The two actions are distinguished, so a dry run tells you which aliases the revision does not have yet.

## Errors

| Code                                                                                               | When                                                                                                                                                         |
| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `MANIFEST_NOT_FOUND`, `MANIFEST_INVALID`, `MANIFEST_TYPE_MISMATCH`, `MANIFEST_VERSION_UNSUPPORTED` | The manifest is absent or unusable — including an entry whose `source` file does not exist.                                                                  |
| `DEFINITION_ALIAS_INVALID`                                                                         | A manifest entry's `alias` fails `^[a-z0-9_-]{6,42}$`.                                                                                                       |
| `BLOB_NOT_ACCESSIBLE`, `BLOB_NOT_WORKFLOW`                                                         | The blob is absent or unreachable with this key, or is not a workflow blob.                                                                                  |
| `REVISION_NOT_ACCESSIBLE`, `REVISION_NOT_WRITABLE`                                                 | The revision is unreachable, or is not `ready` in phase `draft`/`managed`. A `commit`-phase revision reaches this.                                           |
| `DEFINITION_CATEGORY_UNKNOWN`                                                                      | The document's `type` is unrecognized and no `category:` is declared, or the declared category contradicts the document.                                     |
| `DEFINITION_NOT_ACCESSIBLE`                                                                        | A `--definition` alias is not in the manifest.                                                                                                               |
| `ALIAS_IN_USE`                                                                                     | The server refused the create: that alias already exists in that category on this revision.                                                                  |
| `LIMIT_EXCEEDED`                                                                                   | The revision is at its per-category definition cap.                                                                                                          |
| `PLAYGROUND_LAYOUT_IMMUTABLE`                                                                      | The playground's `layout` differs from the one canonicalized at creation — including a document with no `layout` at all, which canonicalizes to `free_form`. |
| `PLAYGROUND_POSITION_INVALID`                                                                      | A component's grid position exceeds the layout's `columns`.                                                                                                  |
| `FORMAT_UNSUPPORTED`, `FORMAT_PARSE_ERROR`                                                         | A `source` 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.                                                                                                                             |
| `DEFINITION_LIST_TRUNCATED`                                                                        | Advisory, on stderr: the listing may be incomplete. The exit code stays `0`.                                                                                 |

`push` has no rollback. It uploads definitions in manifest order, and a failure on the third leaves the first two
uploaded — which is a state, not a corruption: re-running after the fix re-uploads all three.

Every code above, with its remediation, is in [Error codes](/cli/error-codes).

## See also

* [`blobhub workflow pull`](/cli/workflow/commands/pull) — the read half of the pair.
* [`blobhub workflow deploy`](/cli/workflow/commands/deploy) — compile, upload only what changed, and check it.
* [`blobhub workflow check`](/cli/workflow/commands/check) — what `push` deliberately does not run for you.
* [Create Definition](/blob-types/workflow/operations/create-definition) and
  [Upload Definition](/blob-types/workflow/operations/upload-definition) — the two calls behind a create.
* [Playground definition format](/blob-types/workflow/playgrounds/definition-format) — where `layout` and grid
  positions come from.
