Workflow CLI command reference
Every Workflows CLI command with its flags, selectors, JSON output, and exit behavior, for deploying definitions and driving instances.
@sanity/workflow-cli deploys workflow definitions, inspects instances, and recovers stuck runs from a terminal or a CI job. This page lists every command with its arguments, flags, output, and exit behavior. For the setup every command here assumes, installing the CLI, authenticating, and writing sanity.workflow.ts, see Configure and deploy workflow definitions.
Run a command with npx @sanity/workflow-cli <command>. That form needs no install and uses the copy in your project when one is there. The package ships a single binary named sanity-workflows, so a project-local install runs the same commands as sanity-workflows <command>. Every command id also nests under the workflows topic, which is what lets a host CLI mount the package and surface the same command as <host> workflows <command>. Definition commands use the plural definitions topic and generation uses blueprints generate; definition and blueprint are accepted as aliases.
# Deploy the definitions in one deployment, start a run, then move it along
npx @sanity/workflow-cli deploy --deployment production
npx @sanity/workflow-cli start article-review --deployment production
npx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6
npx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6 --activity write --action submit# Deploy the definitions in one deployment, start a run, then move it along
pnpm dlx @sanity/workflow-cli deploy --deployment production
pnpm dlx @sanity/workflow-cli start article-review --deployment production
pnpm dlx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6
pnpm dlx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6 --activity write --action submit# Deploy the definitions in one deployment, start a run, then move it along
yarn dlx @sanity/workflow-cli deploy --deployment production
yarn dlx @sanity/workflow-cli start article-review --deployment production
yarn dlx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6
yarn dlx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6 --activity write --action submit# Deploy the definitions in one deployment, start a run, then move it along
bunx @sanity/workflow-cli deploy --deployment production
bunx @sanity/workflow-cli start article-review --deployment production
bunx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6
bunx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6 --activity write --action submitSelect a deployment, a partition, or an instance
Three flag names appear across the CLI and they do not mean the same thing on every command. --deployment and --partition are always mutually exclusive, and every command that accepts both rejects the pair. Commands that take an instance id need neither, because an instance id is globally unique and carries its own partition.
Commands |
|
|
|---|---|---|
| The one deployment to deploy. | Every deployment carrying the partition. A partition is an environment group, so this is a fan-out, not a picker. |
| The one deployment to act on. | The deployment carrying the partition, while the partition names exactly one. |
| Narrows where the instance is looked up. Optional. | Narrows where the instance is looked up. Optional. |
| Not accepted. | A query filter, which also narrows which resources are searched. |
| The deployment to reset, or with | The partition to reset, while it names exactly one deployment. Not valid with |
| Not accepted. The command covers the whole config. | Not accepted. The command covers the whole config. |
The deploy row is the one that surprises people. On start, definitions diff, and definitions delete, --partition resolves to exactly one deployment and errors when it cannot. On deploy it deploys every deployment carrying the partition instead. On the instance-keyed commands it is only a narrower: it limits which resources are searched, and never has to resolve to one deployment.
Using tag in config or scripts
--tag, --all-tags, and a deployment tag in sanity.workflow.ts still work and print a deprecation warning on stderr. If your config or scripts use them, rename each to partition (--partition, --all-partitions) and keep the same value. See Deployments, partitions, and resources.
With no selector at all, a command that needs one deployment falls back to the sole deployment when the config declares exactly one. When several are declared, an interactive terminal prompts for one and a non-interactive shell fails with Multiple deployments configured — pass --deployment or --partition. (deploy adds , or --all-partitions to deploy every deployment to that message.) Read commands need no selector in any case: without one, they span every distinct resource the config mentions.
An instance id looks like prod.wf-instance.a1b2c3d4e5f6. When the id carries a leading partition segment the CLI probes the resources under that partition first and falls back to the full fan-out on a miss, so the prefix is a speed hint and never a requirement. If several deployments hold the same id, an interactive terminal asks you to pick one; with --json or in a non-interactive shell the command fails, lists each candidate as name (dataset), and asks for --deployment.
Find the config
Every command that reads sanity.workflow.ts looks in the directory you run it from, then in each parent directory, and uses the first config it finds. Pass --path with a config file, or with a directory to start that search from. blueprints generate writes, and deploy checks, the generated Blueprint files next to the config file, not in the directory you ran the command from.
Read a resource without a config
The read commands list, show, tail, diagnose, definitions list, and definitions show can read one resource you name, with or without a config. Pass --project-id and --dataset (-p and -d) together for a dataset, or --media-library-id for a media library. The CLI then loads no config and reads only that resource, so these flags cannot be combined with --deployment or --path. --partition still filters. Commands that write always act through a deployment in sanity.workflow.ts.
npx @sanity/workflow-cli definitions list --project-id <your-project-id> --dataset production
npx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6 -p <your-project-id> -d productionpnpm dlx @sanity/workflow-cli definitions list --project-id <your-project-id> --dataset production
pnpm dlx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6 -p <your-project-id> -d productionyarn dlx @sanity/workflow-cli definitions list --project-id <your-project-id> --dataset production
yarn dlx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6 -p <your-project-id> -d productionbunx @sanity/workflow-cli definitions list --project-id <your-project-id> --dataset production
bunx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6 -p <your-project-id> -d productionRead the output as JSON
--json is available on start, fire-action, list, show, diagnose, definitions list, definitions show, and definitions validate. The other commands have no JSON mode. Rows from list and definitions list carry the partition in a partition field. One payload convention runs across all of them:
- Write commands emit the operation envelope, where
instanceIdcarries the document_id. showcommands print the fetched document exactly as stored.- List commands print the row view of the table, each row annotated with the
resourceit came from, under a top-leveltruncatedflag.
List commands treat --json as all-or-nothing across resources. The rendered path tolerates a resource the token cannot read, notes the failure in place, and prints the rest; the JSON path rejects the whole read instead, so a script never mistakes a partial listing for a complete one.
Exit codes
Every command exits 0 on success. The CLI sets two other codes itself, and hands anything it does not recognize to oclif, which prints a stack trace and chooses its own.
Code | When |
|---|---|
| The command completed. A write that found nothing to change also exits |
| The failure path the CLI owns: no
|
| You interrupted an interactive prompt with Ctrl+C. This is the Unix 128 + SIGINT convention. |
| The command line could not be parsed: an unknown command or flag, a missing or unexpected argument, or a flag value of the wrong type. The CLI prints the error and the command's usage. |
Multi-target runs are deliberately tolerant. deploy --all-partitions continues past a deployment that failed, prints a summary naming each failure, and exits 1; deploys are idempotent, so re-running is safe. list and definitions list do the same across resources. A run with a single target rethrows instead of summarizing, and an authentication rejection stops any run at once, because a dead token is never local to one target.
Commands
Each entry names the command, one representative invocation, and its complete argument and flag contract. Arguments are positional and shown in upper case; flags marked required have no default the command can fall back to.
deploy: validate, diff, and ship definitions
deploy validates the definitions in the selected deployment, then writes them to the resource that the workflowResource of that deployment names. Validation runs offline before any network write, so a run spanning several deployments cannot leave a partial deploy behind a broken batch. Definitions are content-addressed: deploying an unchanged definition creates no new version, which is what makes re-running a failed deploy safe.
When workflows.blueprint.ts exists beside the config, deploy checks generated-runtime alignment for the whole config before token resolution or writes. Drift and missing handlers stop deployment. --check and --dry-run include this check; --only, --deployment, and --partition do not narrow it. There is no bypass flag. Without a generated tree, deploy reports runtime needs and continues.
Before writing, deploy also checks for a likely lost partition. When it would deploy to the default partition of a workflow resource whose definitions all live in other partitions, it warns and names those partitions. In an interactive terminal it then asks whether to continue, and answering no exits before anything is written. A --dry-run or a non-interactive run prints the warning and continues.
Without a generated tree, deploy prints one summary line per selected deployment, counting the effect drains, heartbeats, and start watchers it needs. Pass --verbose for the full report. --dry-run runs every check a real deploy runs before its first write, including the reader-floor acknowledgement and the project role check, so it fails on any batch the deploy would reject.
On deploy alone, --partition deploys every deployment carrying the partition rather than resolving to one. A deploy that creates new definition versions also shares those documents with Sanity by default in every environment; --no-share-defs opts out for one run.
# Validate offline, diff against what is deployed, then deploy
npx @sanity/workflow-cli deploy --check --deployment production
npx @sanity/workflow-cli deploy --dry-run --deployment production
npx @sanity/workflow-cli deploy --deployment production# Validate offline, diff against what is deployed, then deploy
pnpm dlx @sanity/workflow-cli deploy --check --deployment production
pnpm dlx @sanity/workflow-cli deploy --dry-run --deployment production
pnpm dlx @sanity/workflow-cli deploy --deployment production# Validate offline, diff against what is deployed, then deploy
yarn dlx @sanity/workflow-cli deploy --check --deployment production
yarn dlx @sanity/workflow-cli deploy --dry-run --deployment production
yarn dlx @sanity/workflow-cli deploy --deployment production# Validate offline, diff against what is deployed, then deploy
bunx @sanity/workflow-cli deploy --check --deployment production
bunx @sanity/workflow-cli deploy --dry-run --deployment production
bunx @sanity/workflow-cli deploy --deployment productionsanity-workflows deploy(--deployment, --partition, --all-partitions, --dry-run, --check, --only, --verbose, --share-defs / --no-share-defs): Rendered output only
Validate, diff, and deploy the definitions in the selected deployment to the resource it binds.
Parameters
--deployment
string
Deployment name, the unique identity of one deployment in the config. Mutually exclusive with
--partition.--partition
string
Workflow environment partition, for example
prodortest. Ondeploythis deploys every deployment carrying the partition, not one, because a partition is an environment group. Mutually exclusive with--deployment.--all-partitions
boolean
Deploy every deployment in the config. Default
false. Mutually exclusive with--deploymentand--partition.--dry-run
boolean
Validate, then diff each definition against the deployed version and print the diff. Writes nothing. Default
false.--check
boolean
Validate the definitions and stop. Never contacts the dataset and never resolves a token, so it runs offline and unauthenticated. Default
false. Combining it with--dry-runfails withPass either --check or --dry-run, not both.--only
string
Limit deploy, check, or dry-run to one definition by name. Every targeted deployment must declare it; a name no deployment declares fails with
No definition named "<name>".before any deployment picker runs.--verbose
boolean
When no generated runtime sits beside the config, print the full report of the Sanity Functions the selected deployments need instead of the one-line-per-deployment summary. Default
false.--share-defs / --no-share-defs
boolean
Share the definition documents this deploy newly creates with Sanity: the full document verbatim, plus the project and dataset it was deployed to. Never content documents, instances, or your auth token. Sharing is the default in every environment, CI, non-TTY, and
DO_NOT_TRACKincluded. A failed share warns and never fails the deploy.
blueprints generate: generate an experimental runtime
blueprints generate derives Sanity Functions from the workflow definitions in your config and writes them beside the config. It is experimental and not ready for production use. For setup, file ownership, deployment order, and current limits, see Try the generated runtime.
The command covers every deployment and accepts no deployment or partition selector. Each deployment must be a named export from the config under its own name. Generation validates definitions, checks the exports and required dependencies, and reports the runtime needs before writing files.
The runtime-needs report describes each drain and start-watcher trigger, the heartbeat’s separate workflow-tick and effect-recovery scopes, and its recovery budget. It warns about creates-only watchers, unrestricted subject types, and filters whose dependencies require observing every update. Review those warnings before deploying the generated Functions.
npx @sanity/workflow-cli blueprints generate
npx @sanity/workflow-cli blueprints generate --checkpnpm dlx @sanity/workflow-cli blueprints generate
pnpm dlx @sanity/workflow-cli blueprints generate --checkyarn dlx @sanity/workflow-cli blueprints generate
yarn dlx @sanity/workflow-cli blueprints generate --checkbunx @sanity/workflow-cli blueprints generate
bunx @sanity/workflow-cli blueprints generate --checksanity-workflows blueprints generate(--check): Rendered output only
Generate runtime files, or compare the current files with the generated result.
Parameters
--check
boolean
Default
false. Render the expected files in memory and compare them with disk. Write nothing. Exit0when the tree matches, or1when files or wiring need attention.
Generation rewrites generated modules, creates missing handler stubs, and preserves existing handlers. It reports orphaned handlers, case collisions, and Blueprint wiring that needs manual changes. It deletes nothing.
With --check, a missing file reports missing and an edited generated file reports differs. Orphaned handlers or registries, case collisions, and unresolved Blueprint wiring also fail the check. A missing handler fails even if the other generated files match.
A stale function directory also fails the check. That is a directory under the generated functions/ tree whose index.ts carries the generator's header but which the current definitions no longer produce, such as the directory left behind when a deployment is renamed. blueprints generate lists it for you to remove, and deploy prints a warning naming it and continues. A directory whose index.ts has no generator header is yours and is never reported.
deploy also runs the alignment check when workflows.blueprint.ts exists beside the config. Keep blueprints generate --check in CI when you want a standalone check without a definition deployment. After upgrading the generator, regenerate, review preserved handlers, deploy definitions, then redeploy Functions.
start: create an instance from a deployed definition
start creates a workflow instance from a definition already deployed under the selected deployment. Supply a value for each field the definition declares with initialValue: {type: 'input'} using --field name=value. Values are parsed as JSON and fall back to a plain string, so a reference field takes a JSON object carrying the global id and type of the document.
If the engine creates and primes the instance but its first auto-advance fails, start reports the run as started rather than failed, because the instance exists. It settles on the next tick, or you can re-run with --instance-id set to the reported id, which resumes the earlier attempt instead of creating a duplicate.
Runtime-supplied refs, such as a --field subject or a release ref, may target the deployment's workflowResource or any resource it binds in resourceAliases, in another dataset or another project. Anything else fails with RefResourceUndeclaredError. To start a workflow on content in another resource, bind that resource even when no definition references the alias. The CLI reaches each bound resource with the same token and API host, so that login must be a member of every bound project. Instance commands such as fire-action, abort, and diagnose use the bindings of the deployment that owns the instance.
npx @sanity/workflow-cli start article-review \
--deployment production \
--field subject='{"id":"dataset:<your-project-id>:production:article-1","type":"article"}'pnpm dlx @sanity/workflow-cli start article-review \
--deployment production \
--field subject='{"id":"dataset:<your-project-id>:production:article-1","type":"article"}'yarn dlx @sanity/workflow-cli start article-review \
--deployment production \
--field subject='{"id":"dataset:<your-project-id>:production:article-1","type":"article"}'bunx @sanity/workflow-cli start article-review \
--deployment production \
--field subject='{"id":"dataset:<your-project-id>:production:article-1","type":"article"}'sanity-workflows start NAME(NAME, --deployment, --partition, --version, --field, --instance-id, --json): `{instanceId, definition, version, currentStage, completedAt}` with `--json`
Start a workflow instance from a deployed definition, seeding its input-sourced fields.
Parameters
NAME
string
The workflow definition name, as declared by
defineWorkflow.--deployment
string
Deployment name, the unique identity of one deployment in the config. Mutually exclusive with
--partition.--partition
string
Workflow environment partition, for example
prodortest. Selects the deployment to act on while the partition names exactly one; a partition spanning several fails and asks for--deployment. Mutually exclusive with--deployment.--version
integer
Definition version to start from. Defaults to the highest deployed version.
--field
string[]
Initial value for one declared input-sourced field, as
name=value. Repeatable. Each value is JSON-parsed and falls back to a plain string; reference kinds take a JSON object with a global document referenceidand a documenttype.--instance-id
string
Start under this instance id. The id is the idempotency key of the start: passing the id of a start that failed partway resumes it, and an already-settled start replays as a no-op. Omit it to mint a fresh id.
--json
boolean
Emit structured JSON on stdout instead of the rendered view.
fire-action: resolve an activity, or list what can be fired
fire-action fires one action on one activity of the current stage of an instance. Omit --action and it lists every action on that stage instead, each marked fireable or not with the reason it is disabled and the params it takes. Passing --action without --activity fails and asks for the activity.
The write is attributed to whoever the configured token authenticates. There is no impersonation flag, and the engine resolves the acting identity from the token rather than from anything you pass. Firing an action on an activity that is no longer active changes nothing and says so.
# List what can be fired right now
npx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6
# Fire one action
npx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6 \
--activity write --action submit --param note='ready for review'# List what can be fired right now
pnpm dlx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6
# Fire one action
pnpm dlx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6 \
--activity write --action submit --param note='ready for review'# List what can be fired right now
yarn dlx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6
# Fire one action
yarn dlx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6 \
--activity write --action submit --param note='ready for review'# List what can be fired right now
bunx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6
# Fire one action
bunx @sanity/workflow-cli fire-action prod.wf-instance.a1b2c3d4e5f6 \
--activity write --action submit --param note='ready for review'sanity-workflows fire-action INSTANCEID(INSTANCEID, --activity, --action, --param, --deployment, --partition, --json): `{instanceId, activity, action, changed, cascaded, currentStage, ranOps}` with `--json`
Fire an action to resolve a waiting activity, or list the actions available on the current stage of the instance.
Parameters
INSTANCEID
string
The workflow instance id.
--activity
string
The activity the action belongs to. Required to fire; omit
--actionto list instead.--action
string
The action to fire. Omit it to list the actions available on the instance.
--param
string[]
An action param as
key=value. Repeatable. Values are JSON-parsed and fall back to a plain string; the engine validates each against the declared type of the param.--deployment
string
Narrows the instance search to the resource that deployment targets. Never required: an instance id is globally unique. The partition still comes from the loaded instance, not from this flag. Mutually exclusive with
--partition.--partition
string
Narrows the instance search to the resources deployed under that partition. Never required. Mutually exclusive with
--deployment.--json
boolean
Emit structured JSON on stdout instead of the rendered view.
list: find instances
list lists workflow instances, in-flight only unless you pass --include-completed. Without --partition it spans every distinct resource the config mentions, and prints a banner per resource when it spans more than one. --partition here is a query filter, not a deployment selector: it filters rows and narrows which resources are searched.
When the read spans several resources, one the token cannot read is noted in place, the rest still render, and the run exits 1. --limit caps rows per resource at 50 by default; the output says when a page was clipped.
To find work assigned to a person or offered to their roles, pass --assignment-user, repeat --assignment-role for their project roles, and select the held and routed states. Replace ACCOUNT_USER_ID with the person’s account-global user ID, not a project membership ID. Replace editor with a project role they hold.
npx @sanity/workflow-cli list --partition prod \
--assignment-user ACCOUNT_USER_ID \
--assignment-role editor \
--assignment-state held --assignment-state routed \
--jsonpnpm dlx @sanity/workflow-cli list --partition prod \
--assignment-user ACCOUNT_USER_ID \
--assignment-role editor \
--assignment-state held --assignment-state routed \
--jsonyarn dlx @sanity/workflow-cli list --partition prod \
--assignment-user ACCOUNT_USER_ID \
--assignment-role editor \
--assignment-state held --assignment-state routed \
--jsonbunx @sanity/workflow-cli list --partition prod \
--assignment-user ACCOUNT_USER_ID \
--assignment-role editor \
--assignment-state held --assignment-state routed \
--jsonEach JSON row includes assignment: {unrouted, routed, held} counts for active activities in the current open stage. held counts direct assignments to that person; routed counts unassigned work offered through their supplied roles. unrouted counts work with neither a person nor a role selected. These counts do not mean the person can perform an action. Without --json, the same counts appear in the assignment u/r/h column.
npx @sanity/workflow-cli list --definition article-review --failed --partition prodpnpm dlx @sanity/workflow-cli list --definition article-review --failed --partition prodyarn dlx @sanity/workflow-cli list --definition article-review --failed --partition prodbunx @sanity/workflow-cli list --definition article-review --failed --partition prodsanity-workflows list(--partition, --include-completed, --failed, --definition, --document, --assignment-user, --assignment-role, --assignment-state, --limit, --json, --project-id, -p, --dataset, -d, --media-library-id): `{instances, truncated}` with `--json`
List workflow instances across the resources the config mentions.
Parameters
--partition
string
Workflow environment partition, for example
prodortest. A query filter that also narrows which resources are searched. Omit it to span every resource the config mentions.--include-completed
boolean
Include completed and aborted instances. Default
false, which lists in-flight instances only.--failed
boolean
Only instances with at least one activity in the
failedstatus, in any stage. Defaultfalse.--definition
string
Only instances of this workflow definition, matched against the
definitionfield of the instance.--document
string
Only instances that reference this document. Takes a resource-qualified global document reference, for example
dataset:YOUR_PROJECT_ID:production:article-1.--assignment-user
string
Account-global user ID for viewer-scoped assignment filtering and counts.
--assignment-role
string
A literal project role held by the viewer. Repeat for multiple roles. Requires --assignment-user; role aliases do not add inbox ownership.
--assignment-state
string
Include unrouted, routed, or held activities. Repeat for multiple states. Requires --assignment-user. Routed means offered through a supplied role; held means assigned directly to the supplied user.
--limit
integer
Maximum rows to return per resource. Default
50.--json
boolean
Emit structured JSON on stdout instead of the rendered view.
--project-id, -p
string
Project ID of a dataset to read instead of the config. Requires
--dataset. Not valid with--deployment,--path, or--media-library-id.--dataset, -d
string
Dataset to read instead of the config. Requires
--project-id.--media-library-id
string
Media library to read instead of the config. Not valid with
--project-id,--dataset,--deployment, or--path.
show: read one instance in full
show prints the stages of one instance, the activities in each with their status, and any pending effects. History is left out unless you pass --include history, because it grows without bound. --json always carries the complete stored document regardless of --include.
For an in-flight instance, rendered output also evaluates current state and explains faults such as missing references. If evaluation fails, show warns and displays stored state with reference availability unknown. Completed and aborted instances, and show --json, are displayed without this evaluation.
show locates the instance by fanning out across every resource the config mentions, so it takes no deployment selector. An id no resource holds exits 1.
npx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6 --include historypnpm dlx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6 --include historyyarn dlx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6 --include historybunx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6 --include historysanity-workflows show INSTANCEID(INSTANCEID, --partition, --include, --json): The complete instance document with `--json`
Show the state, activities, and pending effects of one workflow instance.
Parameters
INSTANCEID
string
The workflow instance document id.
--partition
string
Workflow environment partition, for example
prodortest. A query filter that also narrows which resources are searched. Omit it to span every resource the config mentions.--include
string[]
Extra sections for the rendered output. Repeatable. The only accepted value is
history.--json
boolean
Emit structured JSON on stdout instead of the rendered view.
tail: stream new history entries
tail subscribes to one instance and prints each new history entry as it lands in the dataset. It runs until you stop it: Ctrl+C or SIGTERM unsubscribes and exits 0. A dropped subscription exits 1 rather than hanging.
tail prints the timestamp and type of each entry, not its payload. Read the payload with show --include history or show --json. There is no --json mode on tail.
npx @sanity/workflow-cli tail prod.wf-instance.a1b2c3d4e5f6pnpm dlx @sanity/workflow-cli tail prod.wf-instance.a1b2c3d4e5f6yarn dlx @sanity/workflow-cli tail prod.wf-instance.a1b2c3d4e5f6bunx @sanity/workflow-cli tail prod.wf-instance.a1b2c3d4e5f6sanity-workflows tail INSTANCEID(INSTANCEID, --partition): Rendered output only
Stream new history entries on a workflow instance as they land in the dataset.
Parameters
INSTANCEID
string
The workflow instance id to tail.
--partition
string
Workflow environment partition, for example
prodortest. A query filter that also narrows which resources are searched. Omit it to span every resource the config mentions.
diagnose: explain why an instance is not progressing
diagnose classifies an instance as progressing, waiting, blocked, stuck, completed, or aborted, explains why, and lists the remediations the engine considers available. A waiting result distinguishes an action available to this caller, a manual action unavailable to this caller, and automation. Unassigned work has no selected holder; it is not automatically actionable. The command reads state without writing it.
A stuck verdict identifies the primary cause in diagnosis.cause. The command also shows current transition conditions and available recovery operations:
Cause | Meaning |
|---|---|
| A required or currently needed content reference is unavailable. The evidence identifies the field and reference. |
| An effect failed and blocks its activity. |
| An effect was claimed but no outcome was recorded. |
| An activity is in a failed state. |
| Activities have resolved, but no exit transition condition is true. |
| Every activity is resolved, but an exit transition reads data that is missing or unreadable (GROQ |
Missing-reference details distinguish content that was deleted, cannot be read, or exists outside the workflow perspective when the checks establish that distinction. A failed read does not prove deletion. Existing activity and effect faults retain their recovery operations. See When referenced content is deleted for repair guidance.
npx @sanity/workflow-cli diagnose prod.wf-instance.a1b2c3d4e5f6pnpm dlx @sanity/workflow-cli diagnose prod.wf-instance.a1b2c3d4e5f6yarn dlx @sanity/workflow-cli diagnose prod.wf-instance.a1b2c3d4e5f6bunx @sanity/workflow-cli diagnose prod.wf-instance.a1b2c3d4e5f6sanity-workflows diagnose INSTANCEID(INSTANCEID, --deployment, --partition, --json): `{instanceId, stage, diagnosis, remediations, transitions}` with `--json`
Explain whether a workflow instance is progressing, why it is not, and what would unstick it.
Parameters
INSTANCEID
string
The workflow instance id.
--deployment
string
Narrows the instance search to the resource that deployment targets. Never required: an instance id is globally unique. The partition still comes from the loaded instance, not from this flag. Mutually exclusive with
--partition.--partition
string
Narrows the instance search to the resources deployed under that partition. Never required. Mutually exclusive with
--deployment.--json
boolean
Emit structured JSON on stdout instead of the rendered view.
abort: hard-stop an in-flight instance
abort stops an in-flight instance where it stands. Pending effects are cancelled, the stage guards it holds are removed, and the instance is marked terminal in its current stage. It deletes nothing and moves the instance to no other stage.
Aborting an instance that is already terminal changes nothing and reports when it terminated. Abort before deleting: nuke --instance refuses an in-flight instance precisely so its effects and children are cleaned up first.
npx @sanity/workflow-cli abort prod.wf-instance.a1b2c3d4e5f6 \
--reason 'superseded by relaunch'pnpm dlx @sanity/workflow-cli abort prod.wf-instance.a1b2c3d4e5f6 \
--reason 'superseded by relaunch'yarn dlx @sanity/workflow-cli abort prod.wf-instance.a1b2c3d4e5f6 \
--reason 'superseded by relaunch'bunx @sanity/workflow-cli abort prod.wf-instance.a1b2c3d4e5f6 \
--reason 'superseded by relaunch'sanity-workflows abort INSTANCEID(INSTANCEID, --reason, --deployment, --partition): Rendered output only
Abort an in-flight workflow instance: cancel pending effects, remove stage guards, and mark it terminal where it stands.
Parameters
INSTANCEID
string
The workflow instance id.
--reason
string
Free-text reason, recorded on the history entry for audit.
--deployment
string
Narrows the instance search to the resource that deployment targets. Never required: an instance id is globally unique. The partition still comes from the loaded instance, not from this flag. Mutually exclusive with
--partition.--partition
string
Narrows the instance search to the resources deployed under that partition. Never required. Mutually exclusive with
--deployment.
set-stage: force an instance into a stage
set-stage moves an instance to any stage its pinned definition declares, ignoring the declared transitions and their conditions. This is the administrative override the engine provides.
It is not a full bypass. The enter lifecycle of the target stage still runs, so auto-activities start and stage guards reconcile, and the cascade that follows the move can advance the instance onward immediately. Omit --to on an interactive terminal to pick from the stages the pinned definition declares; the picker marks the current stage and offers every declared stage. A non-interactive shell fails asking for --to. Moving an instance to the stage it is already in changes nothing, and a terminal instance never moves.
npx @sanity/workflow-cli set-stage prod.wf-instance.a1b2c3d4e5f6 \
--to review --reason 'unblock for demo'pnpm dlx @sanity/workflow-cli set-stage prod.wf-instance.a1b2c3d4e5f6 \
--to review --reason 'unblock for demo'yarn dlx @sanity/workflow-cli set-stage prod.wf-instance.a1b2c3d4e5f6 \
--to review --reason 'unblock for demo'bunx @sanity/workflow-cli set-stage prod.wf-instance.a1b2c3d4e5f6 \
--to review --reason 'unblock for demo'sanity-workflows set-stage INSTANCEID(INSTANCEID, --to, --reason, --deployment, --partition): Rendered output only
Force a workflow instance into a stage regardless of its declared transitions and filters.
Parameters
INSTANCEID
string
The workflow instance id to move.
--to
string
Target stage name. Any stage the pinned definition of the instance declares is accepted. Omit it on an interactive terminal to pick from a list.
--reason
string
Free-text reason, recorded on the history entry for audit.
--deployment
string
Narrows the instance search to the resource that deployment targets. Never required: an instance id is globally unique. The partition still comes from the loaded instance, not from this flag. Mutually exclusive with
--partition.--partition
string
Narrows the instance search to the resources deployed under that partition. Never required. Mutually exclusive with
--deployment.
reset-activity: re-run or skip a failed activity
reset-activity returns a failed activity to active so it can run again. Pass --skip to mark it skipped instead, which is what lets an exit transition gated on that activity fire without the work being done. Both forms continue the workflow cascade.
The activity must be in the current stage of the instance, named exactly as the definition declares it. An activity already at the target status changes nothing, and a terminal instance never resets.
# Re-run it
npx @sanity/workflow-cli reset-activity prod.wf-instance.a1b2c3d4e5f6 legal-review
# Or bypass it so the exit transition can fire
npx @sanity/workflow-cli reset-activity prod.wf-instance.a1b2c3d4e5f6 legal-review --skip# Re-run it
pnpm dlx @sanity/workflow-cli reset-activity prod.wf-instance.a1b2c3d4e5f6 legal-review
# Or bypass it so the exit transition can fire
pnpm dlx @sanity/workflow-cli reset-activity prod.wf-instance.a1b2c3d4e5f6 legal-review --skip# Re-run it
yarn dlx @sanity/workflow-cli reset-activity prod.wf-instance.a1b2c3d4e5f6 legal-review
# Or bypass it so the exit transition can fire
yarn dlx @sanity/workflow-cli reset-activity prod.wf-instance.a1b2c3d4e5f6 legal-review --skip# Re-run it
bunx @sanity/workflow-cli reset-activity prod.wf-instance.a1b2c3d4e5f6 legal-review
# Or bypass it so the exit transition can fire
bunx @sanity/workflow-cli reset-activity prod.wf-instance.a1b2c3d4e5f6 legal-review --skipsanity-workflows reset-activity INSTANCEID ACTIVITY(INSTANCEID, ACTIVITY, --skip, --deployment, --partition): Rendered output only
Reset a failed activity on an in-flight instance, back to active to re-run it or skipped to bypass it.
Parameters
INSTANCEID
string
The workflow instance id.
ACTIVITY
string
The activity name, within the current stage of the instance.
--skip
boolean
Mark the activity
skippedinstead of returning it toactive. Defaultfalse.--deployment
string
Narrows the instance search to the resource that deployment targets. Never required: an instance id is globally unique. The partition still comes from the loaded instance, not from this flag. Mutually exclusive with
--partition.--partition
string
Narrows the instance search to the resources deployed under that partition. Never required. Mutually exclusive with
--deployment.
definitions list: list deployed definitions
definitions list lists the definitions deployed in every resource the config mentions, ordered by name with the newest version first, and counts the instances each has and how many are still in flight.
--partition filters rows and narrows which resources are searched; omit it to span them all. When the read spans several resources, one that fails is noted in place, the rest still render, and the run exits 1.
npx @sanity/workflow-cli definitions list --partition prodpnpm dlx @sanity/workflow-cli definitions list --partition prodyarn dlx @sanity/workflow-cli definitions list --partition prodbunx @sanity/workflow-cli definitions list --partition prodsanity-workflows definitions list(--partition, --limit, --name, --json, --project-id, -p, --dataset, -d, --media-library-id): `{definitions, truncated}` with `--json`
List the workflow definitions deployed in the resources the config mentions.
Parameters
--partition
string
Workflow environment partition, for example
prodortest. A query filter that also narrows which resources are searched. Omit it to span every resource the config mentions.--limit
integer
Maximum definitions to return per resource. Default
100.--name
string
Filter to a single workflow definition name, for example
article-review.--json
boolean
Emit structured JSON on stdout instead of the rendered view.
--project-id, -p
string
Project ID of a dataset to read instead of the config. Requires
--dataset. Not valid with--deployment,--path, or--media-library-id.--dataset, -d
string
Dataset to read instead of the config. Requires
--project-id.--media-library-id
string
Media library to read instead of the config. Not valid with
--project-id,--dataset,--deployment, or--path.
definitions show: read one deployed definition
definitions show prints one deployed definition, its latest version unless --version names one. It reads what is stored in the Content Lake, not what your sanity.workflow.ts currently declares.
It refuses every ambiguity rather than choosing. A name deployed under several partitions inside one dataset fails and lists the partitions; a name held by several datasets fails and lists the resources. Pass --partition to resolve either.
npx @sanity/workflow-cli definitions show article-review --partition prod --version 2pnpm dlx @sanity/workflow-cli definitions show article-review --partition prod --version 2yarn dlx @sanity/workflow-cli definitions show article-review --partition prod --version 2bunx @sanity/workflow-cli definitions show article-review --partition prod --version 2sanity-workflows definitions show NAME(NAME, --partition, --version, --json): The complete deployed definition document with `--json`
Show one deployed workflow definition as it is stored.
Parameters
NAME
string
The workflow definition name.
--partition
string
Workflow environment partition, for example
prodortest. A query filter that also narrows which resources are searched. Omit it to span every resource the config mentions.--version
integer
A specific deployed version. Defaults to the latest.
--json
boolean
Emit structured JSON on stdout instead of the rendered view.
definitions diff: compare in-code against deployed
definitions diff diffs one definition as authored in your sanity.workflow.ts against the version deployed to the selected deployment, the latest unless --version names one. Nothing deployed under that name is a legitimate result and renders as a create.
It takes exactly one definition name, where deploy --dry-run diffs every definition in the deployment. Use definitions diff when you want one answer and deploy --dry-run when you want the whole batch. There is no --json mode.
definitions validate: check definition JSON files
definitions validate checks workflow definitions written as JSON files, without a config, a login, or network access. Each file holds one definition or an array of them, in authoring shape or as stored content read back from a deploy. Pass several files to check a parent and its child workflows together. The command prints one line per valid definition and exits non-zero with every problem listed, path-prefixed, when any definition is invalid. --json prints the same {valid, results} report as the MCP workflows_validate_definition tool.
It checks shape, cross-field rules, and GROQ syntax. deploy runs further checks: duplicate names, spawn dependencies, resource bindings, project roles, and the reader-model acknowledgement. A file that cannot be read, is not valid JSON, or does not hold definition objects stops the command with a text error, even with --json.
npx @sanity/workflow-cli definitions validate review.json
npx @sanity/workflow-cli definitions validate parent.json child.json --jsonpnpm dlx @sanity/workflow-cli definitions validate review.json
pnpm dlx @sanity/workflow-cli definitions validate parent.json child.json --jsonyarn dlx @sanity/workflow-cli definitions validate review.json
yarn dlx @sanity/workflow-cli definitions validate parent.json child.json --jsonbunx @sanity/workflow-cli definitions validate review.json
bunx @sanity/workflow-cli definitions validate parent.json child.json --jsonnpx @sanity/workflow-cli definitions diff article-review --deployment productionpnpm dlx @sanity/workflow-cli definitions diff article-review --deployment productionyarn dlx @sanity/workflow-cli definitions diff article-review --deployment productionbunx @sanity/workflow-cli definitions diff article-review --deployment productionsanity-workflows definitions diff NAME(NAME, --deployment, --partition, --version): Rendered output only
Diff an in-code workflow definition against the version deployed to the selected deployment.
Parameters
NAME
string
The workflow definition name. It must be declared by the selected deployment; a name it does not declare fails and lists the ones it does.
--deployment
string
Deployment name, the unique identity of one deployment in the config. Mutually exclusive with
--partition.--partition
string
Workflow environment partition, for example
prodortest. Selects the deployment to act on while the partition names exactly one; a partition spanning several fails and asks for--deployment. Mutually exclusive with--deployment.--version
integer
The deployed version to diff against. Defaults to the latest.
definitions delete: remove a deployed definition
definitions delete deletes every deployed version of a definition, or one version with --version. Orphaned guard documents are removed only when the delete takes the last remaining version. Deleting one version while others survive leaves them in place.
It refuses while any non-terminal instance is pinned to a targeted version. --cascade aborts those instances first and then deletes; the instances are aborted in place and are never deleted, so their history survives. To remove instance documents as well, abort them and then use nuke.
npx @sanity/workflow-cli definitions delete article-review \
--deployment production --cascade --reason 'workflow retired'pnpm dlx @sanity/workflow-cli definitions delete article-review \
--deployment production --cascade --reason 'workflow retired'yarn dlx @sanity/workflow-cli definitions delete article-review \
--deployment production --cascade --reason 'workflow retired'bunx @sanity/workflow-cli definitions delete article-review \
--deployment production --cascade --reason 'workflow retired'sanity-workflows definitions delete NAME(NAME, --deployment, --partition, --version, --cascade, --reason): Rendered output only
Delete a deployed workflow definition, optionally aborting the instances still pinned to it.
Parameters
NAME
string
The workflow definition name.
--deployment
string
Deployment name, the unique identity of one deployment in the config. Mutually exclusive with
--partition.--partition
string
Workflow environment partition, for example
prodortest. Selects the deployment to act on while the partition names exactly one; a partition spanning several fails and asks for--deployment. Mutually exclusive with--deployment.--version
integer
Delete only this deployed version. Defaults to every version.
--cascade
boolean
Abort every non-terminal instance pinned to the targeted versions, then delete. Default
false, which refuses the delete while any such instance exists.--reason
string
Free-text reason, recorded on each cascade-abort history entry.
nuke: delete engine-owned documents
nuke deletes engine-owned documents. With --deployment or --partition it deletes every instance, definition, and guard under the partition of that deployment, across the workflow resource and every resource its aliases bind. With --instance <id> it deletes one terminal instance plus its guards. Content documents are never touched, and a single-instance delete refuses any id whose _type is not a workflow instance.
This is a development reset for a dataset holding engine documents the versioned upgrade framework cannot yet migrate. Because it deletes raw documents rather than reading them through the engine, it can clear data an older engine wrote that the current one cannot interpret, which definitions delete cannot do. It is not an operational tool, and there is no undo.
nuke always prints a dry-run plan of exactly what it will delete, including under --force. Without --force, partition mode then asks you to type back every project.dataset target space-separated, and instance mode asks a single yes-or-no. A shell that cannot prompt fails rather than blocking. --instance refuses an in-flight instance with Instance is in-flight — abort it first, then delete. Partition mode also refuses when another deployment shares the partition and a swept resource, because guard ids embed only the partition and the sweep could not tell the two apart.
# Reset one development environment, after reviewing the printed plan
npx @sanity/workflow-cli nuke --deployment plugin-dev
# Delete one finished instance and its guards
npx @sanity/workflow-cli nuke --instance plugin-dev.wf-instance.a1b2c3d4e5f6# Reset one development environment, after reviewing the printed plan
pnpm dlx @sanity/workflow-cli nuke --deployment plugin-dev
# Delete one finished instance and its guards
pnpm dlx @sanity/workflow-cli nuke --instance plugin-dev.wf-instance.a1b2c3d4e5f6# Reset one development environment, after reviewing the printed plan
yarn dlx @sanity/workflow-cli nuke --deployment plugin-dev
# Delete one finished instance and its guards
yarn dlx @sanity/workflow-cli nuke --instance plugin-dev.wf-instance.a1b2c3d4e5f6# Reset one development environment, after reviewing the printed plan
bunx @sanity/workflow-cli nuke --deployment plugin-dev
# Delete one finished instance and its guards
bunx @sanity/workflow-cli nuke --instance plugin-dev.wf-instance.a1b2c3d4e5f6sanity-workflows nuke(--deployment, --partition, --instance, --force): Rendered output only
Delete engine-owned documents for a whole deployment partition, or one terminal instance and its guards.
Parameters
--deployment
string
The deployment name to reset. With
--instance, narrows which deployment the instance is looked up in when its partition spans several.--partition
string
The deployment partition to reset, while it names exactly one deployment. Not valid with
--instance, which reads its partition from the instance id.--instance
string
Delete one terminal instance by id, plus its guard documents, instead of a whole partition. The instance must already be completed or aborted.
--force
boolean
Skip the confirmation prompt, for scripts and CI. Default
false. The plan still prints.
Related reading
- Configure and deploy workflow definitions sets up the CLI and the config every command here reads.
- Definitions, instances, and stages explains what a version, an instance, and a cascade are.
- Activities and actions explains what
fire-actionandreset-activityoperate on. - Effects and runtimes explains the queued work
diagnosereports as a failed or hung effect. - Run Workflows with Sanity Functions covers what advances an instance when nobody is at a terminal.
- History and audit trail covers what
tailstreams and whatshow --include historyprints.
Was this page helpful?
Feedback submitted, thanks for helping us improve the docs. Have you tried these alternatives?