Workflows

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

Select 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

--deployment

--partition

deploy

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.

start, definitions diff, definitions delete

The one deployment to act on.

The deployment carrying the partition, while the partition names exactly one.

abort, set-stage, reset-activity, fire-action, diagnose

Narrows where the instance is looked up. Optional.

Narrows where the instance is looked up. Optional.

list, show, tail, definitions list, definitions show

Not accepted.

A query filter, which also narrows which resources are searched.

nuke

The deployment to reset, or with --instance, which deployment to look the instance up in.

The partition to reset, while it names exactly one deployment. Not valid with --instance.

blueprints generate

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

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  --dataset production
npx @sanity/workflow-cli show prod.wf-instance.a1b2c3d4e5f6 -p  -d production

Read 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 instanceId carries the document _id.
  • show commands print the fetched document exactly as stored.
  • List commands print the row view of the table, each row annotated with the resource it came from, under a top-level truncated flag.

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

0

The command completed. A write that found nothing to change also exits 0 and says so.

1

The failure path the CLI owns: no sanity.workflow.ts, an invalid config, no matching deployment, definition, or instance, contradictory flags, a rejected engine write, a refused destructive command, a rejected auth token, or a reader-floor acknowledgement that does not cover the submitted definitions. Also the exit for a multi-target run in which at least one target failed.

blueprints generate --check also exits 1 when the generated runtime differs from the files on disk or needs manual fixes.

130

You interrupted an interactive prompt with Ctrl+C. This is the Unix 128 + SIGINT convention.

2

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
  • sanity-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 prod or test. On deploy this 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 --deployment and --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-run fails with Pass 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_TRACK included. 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 --check
  • sanity-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. Exit 0 when the tree matches, or 1 when 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::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 prod or test. 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 reference id and a document type.

    • --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'
  • 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 --action to 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 \
  --json

Each 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 prod
  • sanity-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 prod or test. 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 failed status, in any stage. Default false.

    • --definition

      string

      Only instances of this workflow definition, matched against the definition field 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 history
  • sanity-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 prod or test. 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.a1b2c3d4e5f6
  • sanity-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 prod or test. 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

document-missing

A required or currently needed content reference is unavailable. The evidence identifies the field and reference.

failed-effect

An effect failed and blocks its activity.

hung-effect

An effect was claimed but no outcome was recorded.

failed-activity

An activity is in a failed state.

no-transition-fires

Activities have resolved, but no exit transition condition is true.

transition-unevaluable

Every activity is resolved, but an exit transition reads data that is missing or unreadable (GROQ null), so it holds the stage, even when a transition declared after it is satisfied. Once the data is written, the next tick or commit checks the transitions again, and the instance moves on only if one is then satisfied. No remediation applies.

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.a1b2c3d4e5f6

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'
  • 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'
  • 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
  • sanity-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 skipped instead of returning it to active. Default false.

    • --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 prod
  • sanity-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 prod or test. 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 2

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 --json
npx @sanity/workflow-cli definitions diff article-review --deployment production
  • sanity-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 prod or test. 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'
  • 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 prod or test. 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
  • sanity-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

Was this page helpful?

Sanity logosanity.ioAll Systems Operational© Sanity 2026
Change site theme