Skip to main content

Run a workflow

Two paths. orca run is the simple one — fire-and-forget a single-group, standalone submission. For multi-group or batched submissions, drop down to orca submission submit.

orca run

orca run <workflow> --run-mode <PURE_SIM|DEVICE_SIM|LIVE> [options]

--run-mode is required on every submission. There is no deployment-level fallback. The 12-row v3.4 resolver combines this with each device's topology sim_override at dispatch time.

Run modeWhat it means
PURE_SIMSoftware simulation. No driver calls, no Chatterbox. Fast.
DEVICE_SIMReal driver wrapping a Chatterbox sim backend. Driver code path runs, no hardware.
LIVEReal driver wrapping the real hardware backend.

Quick patterns

# Fire-and-forget
orca run smc_assay --run-mode PURE_SIM

# Block until terminal, give up after 2 minutes
orca run smc_assay --run-mode PURE_SIM --wait --timeout 120

# Pass workflow variables
orca run smc_assay --run-mode DEVICE_SIM --vars plate_count=2,reagent_batch=L7

# LIVE submission against devices with sim_override
orca run smc_assay --run-mode LIVE --confirm

Flags

FlagRequired?Effect
--run-modeyesPURE_SIM / DEVICE_SIM / LIVE. No default.
--waitnoBlock until the execution is terminal (completed / failed / aborted).
--timeout <s>with --waitSeconds before the CLI gives up (default 300). The execution KEEPS RUNNING — timeout only stops the CLI from waiting. Exit code 50.
--poll <s>with --waitPolling interval (default 0.5s).
--vars KEY=VAL,KEY2=VAL2noPer-submission variable overrides. Best-effort typing: true/false → bool, integer → int, else float, else string.
--profile <path>noPath to a JSON deployment profile loaded into the execution before any thread ticks. Local-only; with --backend cloud exits with EXIT_USAGE.
--confirmLIVE + sim_overrideAcknowledges the LIVE_SUBMISSION_WITH_SIM_OVERRIDES_UNACKNOWLEDGED gate. Without it the runtime refuses.

Output

$ orca run smc_assay --run-mode PURE_SIM
submitted execution 7a3f1c0e (smc_assay)

With --wait the CLI polls and then emits a key-value summary on terminal:

execution 7a3f1c0e
workflow: smc_assay
status: completed
error:

--json form returns the full ExecutionDetailDTO — same shape as GET /api/executions/<id>.

Pitfalls

  • --wait --timeout 60 is NOT a kill switch. It abandons the CLI's poll loop but the execution keeps running. To actually stop an execution use execution stop.
  • --run-mode LIVE against any device with topology sim_override is refused unless --confirm is passed. The refusal includes the override list so you know exactly which devices the LIVE submission would skip.
  • --profile is local-only. Passing it with --backend cloud exits non-zero with a clean redirect — the cloud REST surface does not accept profile paths.
  • --vars is per-submission. It overrides defaults from the workflow's VariableDefinition. To set defaults for every future submission use var set-global.

orca submission submit — multi-group + batched

run is single-group, STANDALONE batch-mode. For everything richer, use submission submit:

# Multi-group: N samples per submission, each in its own group
orca submission submit smc_assay --run-mode PURE_SIM \
--groups-file groups.json

# Batched: join an in-flight ACCEPTING execution of the same workflow
orca submission submit smc_assay --run-mode PURE_SIM \
--groups-file groups.json --batch-mode JOIN_EXISTING

The workflow name is a positional argument, not --workflow. The group spec is a plain path via --groups-file (or inline JSON via --groups-json); there is no @file syntax. The file is a single LabwareGroupDTO object or a JSON array of them.

FlagEffect
<workflow> (positional)The registered @orca.workflow template name.
--run-modeSame as run: PURE_SIM / DEVICE_SIM / LIVE. Required.
--groups-file <path>Multi-group spec file: one LabwareGroupDTO object or a list of them.
--groups-json <json>Same spec inline as a JSON string. Mutually exclusive with --groups-file.
--batch-mode STANDALONE|JOIN_EXISTINGDefault STANDALONE (one fresh execution per submission). JOIN_EXISTING finds an ACCEPTING execution of the same workflow and threads onto it.
--vars KEY=VAL,...Submission-scope variable overrides. Same typing rules as run.
--operator-id <id>Optional operator id recorded on the submission.
--profile <name>Optional deployment-profile name recorded for audit.
--confirmAcknowledges the LIVE + sim_override gate, same as run.

List + detail

orca submission list                           # all submissions on this runtime
orca submission list --execution <exec-id> # one execution's submissions
orca submission detail <submission-id> # one submission's threads + state

ID prefixes work on detail — first 8 hex chars resolve as long as they're unique.

Pitfalls

  • JOIN_EXISTING with no ACCEPTING execution exits CONFLICT (30). It does NOT silently fall back to STANDALONE. To create a fresh execution, drop --batch-mode or pass STANDALONE.
  • Groups are independent submissions in the same wave. Each LabwareGroupDTO gets its own thread spawns. Groups that declare GroupSharing.SHARED_ACROSS_GROUPS on their labware templates converge on shared physical labware — read the template flags before assuming isolation.

Run one method in isolation

To exercise a single method without its surrounding workflow (testing, recovery rehearsal), use method execute:

orca method execute <workflow> <method> \
--labware-start <json> --labware-end <json> \
[--vars <json>] --run-mode <PURE_SIM|DEVICE_SIM|LIVE> [--confirm]

The workflow and method names are positional. --labware-start / --labware-end are JSON maps declaring where the method's labware begins and ends. --run-mode is required (same modes and --confirm gate as run). Works against both backends.

Track an execution

Once submitted, these read-only verbs follow its progress:

orca execution list                                    # all executions
orca execution detail <id> # full snapshot
orca execution threads <id> # thread roll-up
orca execution thread detail <id> <thread-id> # one thread, all fields

execution list takes no filters — it lists every execution known to the loaded system (id, workflow, status, error). Narrow the result yourself with --json | jq if the count is large. detail is the main view: workflow, status, thread counts, and any error.

States

execution list and execution detail report from two different vocabularies.

execution list shows a coarse ExecutionState:

StateMeaning
runningActive: accepting, draining, or stopping, with live threads.
completedEvery thread terminal, no crash or abort.
failedTerminal because a thread crashed with an unhandled error (crash-only). An operator-recoverable error-pause is NOT failed; it stays non-terminal until recovered or the thread actually crashes.
abortedTerminal via execution stop or unload --force.

execution detail shows the finer ExecutionPhase:

PhaseMeaning
acceptingLive; can take more submissions (JOIN_EXISTING).
drainingclose was called: no new submissions, running threads finish.
stoppingA confirmed stop is aborting the execution.
completed / failed / abortedTerminal, same meanings as the list states above.

Pause is not a status on either surface; it is a separate latch. execution detail surfaces error-paused threads in its per-thread block, not as the execution status.

Pitfalls

  • list returns all executions, including terminal ones, and has no server-side filters. Pipe --json through jq to narrow by status if the count is large.
  • thread detail only returns the per-thread snapshot; broader execution context (variables, reservations) lives on the parent. Use execution detail <id> for those.