Skip to content

Run states and errors

A run moves through seven states, and a failed one carries a code, a detail and the stage it failed at.

run.status is the state machine contracts/state-machines/run-v4.json declares.

State Terminal Meaning
queued no accepted and waiting for a worker
running no a worker holds it
awaiting_confirmation no the run is over the projection threshold and needs a --confirm before it starts
awaiting_sample_approval no an existing legacy preview hold or a repair hold; new full builds do not create sample/full pairs
succeeded yes it finished
failed yes it stopped, and the record says why
cancelled yes somebody cancelled it, or a gate expired

The transitions, and who may make them:

Transition From To Actor
create none queued workspace editor
require_confirmation none awaiting_confirmation workspace editor
require_sample_approval none awaiting_sample_approval workspace editor
confirm awaiting_confirmation queued workspace editor
approve_full awaiting_sample_approval queued workspace editor
expire_confirmation awaiting_confirmation cancelled Studio
expire_sample_approval awaiting_sample_approval cancelled Studio
abort_sampled_full awaiting_sample_approval cancelled Studio
start queued running Studio
succeed running succeeded Studio
fail queued, running failed Studio
terminalize_lost_execution running failed Studio
cancel queued, awaiting_confirmation, awaiting_sample_approval, running cancelled workspace editor

A failed run carries failure_code, failure_detail and failed_stage, or it is not a valid record.

mr-data status RUN_ID exits 2 on a failed run. mr-data run exits 2 when the run comes back awaiting_confirmation.

A succeeded run carries outcome:

Value Meaning
version the run wrote a new table version. An absent member means the same
unchanged every source’s bytes matched the predecessor’s, so the worker stopped after acquisition. No transform, no write, no upload, no receipt, no table version. The table’s last_refresh advances and the live pointer stays put

unchanged is legal only on mode refresh. An initial, full, sample or backfill has no predecessor to compare against.

One run command takes six modes.

Mode Flag What it does
sample --sample an explicit bounded experiment. State at least one ceiling; row limits do not limit acquisition time
full --full one progressive acquisition of the whole build. Any required confirmation happens before acquisition; its inspection checkpoint continues automatically
refresh --refresh forward from where the last successful run reached
backfill --backfill one exact window, stated with --window START END
compact --mode compact rewrites adjacent parts of an existing version. Reads no source
replay --mode replay restores the retained raw bytes of --sources-from RUN_ID. Never advances live state and never acquires from a publisher

failed_stage is one of five, in order.

Stage What runs
acquire the worker fetches or redeems every declared source
parse the Reader decodes the bytes into a relation
transform the declared SQL steps run over the source relations
check the worker evaluates the declared checks
persist the worker uploads and stores the table version and its artifacts

The acquire stage reports three phases: fetching, fetched, refused.

Studio stamps run.shape at admission and never re-derives it.

Shape What it is
warm the warm session-worker pool
ready the general ready worker pool, capacity-based
ingestion the bounded-direct ingestion path, legal only for a source-history.v2 bounded direct refresh
batch a batch job

A source with a Reader pin, a generic API configuration, or a document projection needs a per-child memory cgroup and a capture-store mount. Admission stamps it batch. Both pool shapes fall back durably to batch when nothing claims them.

mr-data watch RUN_ID reads an append-only log. event_type has eight values, each with a writer.

Event Written by
run_progress_acquire the worker, once per acquire progress tick
run_progress_parse the worker
run_progress_transform the worker
run_progress_check the worker
run_progress_persist the worker
run_succeeded the worker’s terminal callback
run_failed the worker’s terminal callback, or Studio’s lease watchdog
run_narrative_appended POST /v4/runs/{run_id}/narrative, one per accepted cell

No run_created, run_started or run_cancelled event exists. Nothing writes them. Each record carries schema_version, event_id, workspace_id, run_id, cursor (the SSE id), sequence, event_type, occurred_at, actor_principal_id and payload_digest. Every one of those fields is mandatory. attempt_id and unsealed are optional, and the record accepts nothing else. A progress message is at most 1024 characters. A progress identifier is at most 63.

Studio v4 returns an error as application/problem+json with an x-correlation-id header.

a v4 refusal
{
"schema_version": "4.0.0",
"code": "RECIPE_DIGEST_MISMATCH",
"message": "The registered recipe does not have that digest.",
"request_id": "a2f4…",
"details": [
{ "pointer": "/document/sources/0/limits", "reason": "max_source_bytes is required" }
]
}
Field Required Shape
schema_version yes 4.0.0
code yes ^[A-Z][A-Z0-9_]*$, 3 to 64 characters. A pattern, not a frozen enum
message yes 1 to 2000 characters
request_id yes 1 to 200 characters
details no at most 20 entries, each one of three closed shapes

A details entry is one of three shapes:

  • {pointer, reason} is the validation shape. pointer is at most 512 characters, reason at most 2000.
  • {run_id, projected_bytes, projected_runtime_s, projected_cost} is the body of 409 CONFIRM_REQUIRED.
  • {recorded_cost, requested_cost, ceiling_cost} is the body of 409 DAILY_SPEND_CEILING_EXCEEDED.

A run that answers 409 CONFIRM_REQUIRED already exists, persisted awaiting_confirmation, so the confirmation acts on it rather than repeating the request. projected_cost is a decimal string. Money is never a JSON float here. The plan is flat, so that figure is the platform’s own infrastructure estimate and is never billed to you.

With --json, an error is one object on stderr, and the exit code is 2.

mr-data --json refusal
{
"schema_version": "mr-data-error.v1",
"code": "THIN_STUDIO_RECIPE_DIGEST_MISMATCH",
"error": "The registered recipe does not have that digest.",
"headline": "The registered recipe does not have that digest.",
"remediation": ["…"],
"retry_after_seconds": 30
}

The CLI preserves Studio’s code and adds a prefix. A Studio RECIPE_DIGEST_MISMATCH reaches a script as THIN_STUDIO_RECIPE_DIGEST_MISMATCH, with Studio’s own message. A query refusal takes its family as the prefix and drops the repeated word. Studio’s QUERY_TIMEOUT reaches a script as THIN_QUERY_TIMEOUT, never THIN_QUERY_QUERY_TIMEOUT. Two statuses fold instead of passing through. 401 and 403 both become THIN_AUTHORIZATION_DENIED, with Studio’s code named in the sentence, and 404 becomes THIN_NOT_FOUND.

mr-data raises these before or around a request. They carry no HTTP status.

Code Raised when What the author does
THIN_UNKNOWN_COMMAND the argument list names no command this binary runs mr-data --help lists them
THIN_ARGUMENT_INVALID a flag’s value is not the shape the flag takes fix the argument
THIN_REQUEST_INVALID the request this command would send is not well formed fix the input document or flags
THIN_CONFIG_INVALID a configured origin is not usable check MOSTLYRIGHT_* environment variables
THIN_AUTHENTICATION_FAILED Studio rejected the stored device credential mr-data login
THIN_AUTHORIZATION_DENIED the device key does not carry the authority this call needs check the workspace role. Studio’s own code is in the sentence
THIN_SUBSCRIPTION_REQUIRED cloud answered 402 the workspace has no hosted execution access
THIN_RATE_LIMITED cloud answered 429 honour retry_after_seconds
THIN_TOKEN_EXCHANGE_FAILED the CLI could not reach the cloud token exchange, or it returned an expired token retry. If it persists, cloud’s Studio config is wrong
THIN_STUDIO_UNAVAILABLE cloud answered 503 across every attempt retry later
THIN_STUDIO_UNREACHABLE Studio did not answer retry later
THIN_STUDIO_REFUSED Studio refused the request with no code in the body read http_status on the refusal
THIN_STUDIO_<CODE> Studio refused the request with a v4 code see Studio refusal codes
THIN_NOT_FOUND Studio has no such resource check the identifier. A resource in another workspace reads identically
THIN_RESPONSE_INVALID the CLI could not parse a reply client and backend sit on different contract versions
THIN_RESPONSE_TOO_LARGE a reply exceeded the byte ceiling for its route (1 MiB for JSON) narrow the request
THIN_RECIPE_DOCUMENT_UNREADABLE the CLI could not read the recipe file check the path
THIN_RECIPE_DOCUMENT_INVALID the recipe file is not strict JSON a recipe carries integers, strings, booleans, null, objects and lists, and never a fractional number
THIN_CONFIRMATION_MISMATCH --confirm-name did not match the held name type the name on the page
THIN_DATASET_VERSION_CONFLICT the dataset moved again during a retried rename mr-data dataset show, then rename again
THIN_NO_SEALED_RESULT the run has written nothing to read yet mr-data watch RUN_ID
THIN_NO_CHECK_RESULTS the run has not finished, so checks have not reported mr-data watch RUN_ID
THIN_NO_PREVIEW_SEALED the run composed a multi-part version and wrote no preview mr-data query RUN_ID
THIN_NO_MATCHING_ARTIFACT the run wrote no artifact of the requested --kind ask for a kind it wrote
THIN_NOTHING_LIVE the table carries a promotion but no succeeded run resolves to a version build it once successfully
THIN_NO_RELEASED_VERSION the run released no version check mr-data status
THIN_NO_FINGERPRINT the run’s evidence carries no fingerprint nothing can compare it with another run
THIN_DESTINATION_EXISTS the output path holds a different file a download never overwrites a local file
THIN_ARTIFACT_TOO_LARGE the artifact declares more than 16 GiB not downloadable through the client
THIN_DOWNLOAD_DIGEST_MISMATCH the bytes do not hash to the digest Studio declared retry. Report it if it repeats
THIN_DOWNLOAD_TRUNCATED fewer bytes arrived than Studio declared retry
THIN_DOWNLOAD_OVERRUN more bytes arrived than Studio declared retry
THIN_DOWNLOAD_REFUSED the signed download answered non-200 the session may have expired. Run download again
THIN_VERSION_PART_UNREACHABLE the version names parts for which Studio created no read URL a table missing parts is a table missing rows. The CLI reports nothing as downloaded
THIN_QUERY_STATEMENT_TOO_LARGE the statement is over 64 KiB shorten it. The CLI sent nothing
THIN_QUERY_TIMEOUT the wait ended before the answer the question keeps running. Run the same command again
THIN_QUERY_BINDER_ERROR the statement does not bind against the table check the column names against mr-data peek
THIN_STREAM_REFUSED Studio refused the event-stream request retry watch
THIN_STREAM_UNAVAILABLE the CLI could not re-establish the event stream the run continues. Resume watch
THIN_STREAM_FRAME_INVALID a stream frame carried a body that is not JSON contract mismatch
THIN_SECRET_MATERIAL_INVALID a --part holds more than the vault stores as one value shrink the part
THIN_RESEARCH_SESSION_ENDED no worker took the session this command opened retry
THIN_RESEARCH_SOURCE_FORBIDDEN the source is not one this session may probe open the session against the right dataset
THIN_NOTEBOOK_NOT_RENDERED Studio renders a notebook when the run finishes mr-data watch until then
THIN_COMMAND_UNAVAILABLE this build registers no such command mr-data --help
THIN_COMMAND_HAS_NO_HOSTED_LANE the command does not run on the backend it does not run here
THIN_CLOUD_REFUSED cloud refused and stated nothing usable the sentence quotes what cloud said
THIN_CLOUD_STEP_UP_REQUIRED publishing needs a verification only a signed-in browser finishes open the dashboard and share from that page
THIN_CLOUD_PUBLIC_SHARING_DISABLED the organization does not allow public datasets an owner changes it
THIN_CLOUD_PUBLISHER_PROFILE_REQUIRED the organization has no publisher name set it in team settings

The full client vocabulary is larger. The propose bundle commands, the cancellation journal and the narrative editor each add codes under THIN_PROPOSE_*, THIN_CANCELLATION_* and THIN_NARRATIVE_*. Each states its own sentence and its own fix.

Studio v4 raises these and answers them as problem+json. The message column is Studio’s own wording.

Code HTTP Message What the author does
RECIPE_DIGEST_MISMATCH 409 The registered recipe does not have that digest. pass the digest registration printed
RECIPE_DOCUMENT_NOT_CANONICAL 422 The recipe document cannot be canonicalized. remove fractional numbers and duplicate keys
RECIPE_DOCUMENT_INCOHERENT 422 The recipe document is internally inconsistent. read details[].pointer
RECIPE_UNAVAILABLE 409 This table has no registered recipe to build from. register one
DATASET_ID_REQUIRED 422 Create and categorize the dataset first, then put its id in document.dataset.id. mr-data dataset create
DATASET_CATEGORY_REQUIRED 422 Choose a primary category with dataset set --category before registering a recipe. mr-data dataset categories
DATASET_MISMATCH 409 dataset.id names no V4 dataset of this workspace. check the id
DATASET_NAME_CONFLICT 409 none choose another name
DATASET_ARCHIVED 409 This recipe’s dataset is archived and read-only. unarchive it
CONTRACT_VALIDATION_FAILED 422 none the request does not match the v4 contract
SECRET_UNKNOWN 409 This recipe names a secret this workspace has not enrolled. mr-data keys set NAME
SECRET_UNAVAILABLE 409 The secret this source names is no longer enrolled in this workspace. re-enrol it
CONNECTION_DATASET_REQUIRED 409 Create a dataset and grant it access to this connection, then specify dataset.id. an owner grants it in Settings
CONNECTION_AUTHORITY_MISMATCH 422 Recipe connector authority differs from its saved connection. re-read the connection and re-register
Code HTTP Message What the author does
CLAMPS_REQUIRED 422 A sample run must state at least one clamp. pass --max-rows or --max-source-bytes
CONFIRM_REQUIRED 409 This run is over the projection threshold and needs a confirmation before it starts. re-run with --confirm. The projection is in details
DAILY_SPEND_CEILING_EXCEEDED 409 none the amounts are in details. Wait or raise the ceiling
RUN_WINDOW_REQUIRED 422 A backfill run must state an exact window. pass --window START END
RUN_MODE_UNKNOWN 422 That is not a v4 run mode. one of the six modes
RUN_ALREADY_EXISTS 409 The identical run already ended. Register a revised recipe to run again. revise and re-register
TABLE_RUN_IN_FLIGHT 409 This table already has a mutating run. wait, or cancel the one in flight
TABLE_BUSY 409 A table with a run still in flight cannot start another. wait
TABLE_ARCHIVED 409 This run’s table is archived and no longer builds. unarchive it
BUILD_COMPLETE 409 The latest build already read every source whole. There is nothing to run. nothing to do
REPLAY_SOURCE_REQUIRED 422 A replay must name sources_from_run. pass --sources-from RUN_ID
REPLAY_SOURCE_UNAVAILABLE 409 The named replay source is not a succeeded run of this table. name a succeeded run of the same table
REPLAY_SOURCE_EXPIRED 409 The named run no longer retains its raw snapshot and receipt. replay is no longer possible for it
REPLAY_WORKER_UNAVAILABLE 409 Replay is unavailable until a compatible worker is deployed. wait for the deployment
STATE_TRANSITION_INVALID 409 This full run is not awaiting sample approval. read the run’s current state
STEP_UP_BINDING_MISMATCH 403 Approval requires an interactive step-up bound to this full run version. approve it in the dashboard. A run held behind a PREVIEW does not reach this code: any editor of the workspace releases that one.
ETAG_MISMATCH 412 The run has moved since it was read. re-read and retry
IDEMPOTENCY_KEY_INVALID 422 Idempotency-Key must be 16 to 128 URL-safe characters. fix the header
SCHEDULE_CADENCE_TOO_FREQUENT 422 That schedule refreshes the table more often than the platform allows. slow the cadence
SCHEDULE_CRON_INVALID 422 That cadence is not a satisfiable five-field cron expression. fix the expression
MANUAL_REFRESH_RATE_LIMITED 429 This workspace has requested 1,200 table refreshes in the current hour. wait for the hour to turn
Code HTTP Message What the author does
NOTHING_TO_PROMOTE 409 This table has no succeeded V4 run to promote. build it once
TABLE_NOT_PROMOTED 409 This table is not promoted. the first succeeded run promotes it
TABLE_LIVE 409 A live table cannot be archived. demote it first
TABLE_VERSION_UNAVAILABLE 409 none the version is not readable
TABLE_VERSION_ARTIFACT_UNAVAILABLE 409 This V4 table version has no stored artifact of that kind available. ask for a kind it holds
TABLE_PREVIEW_UNAVAILABLE none none the run wrote no preview
QUERY_TOO_MANY_PARTS none none narrow the read with --field plus --from/--to, or --partition
TABLE_COMPACTION_INELIGIBLE 409 This table has no bounded adjacent part group to compact. nothing to compact
TABLE_COMPACTION_RECIPE_CHANGED 409 Compaction must use the recipe that produced its predecessor version. pass the predecessor’s recipe
CURSOR_INVALID 422 The page cursor is not a position in this listing. start the listing again
Code HTTP Message
STREAM_DOCUMENT_NOT_FOUND 404 No registered connector document in this workspace carries that digest.
STREAM_VENUE_UNAVAILABLE 503 This deployment has not configured a continuous stream worker pool.
STREAM_SUBSCRIPTION_MEMBERS_INVALID 409 This stream already feeds as many promoted tables as one subscription may.
STREAM_RECORDING_MEMBERS_INVALID 422 A recordings listing scopes by member ids.
STREAM_RECORDING_REQUEST_INVALID 422 A recordings listing is scoped by one connector document digest.
RECORDING_MEMBERSHIP_CHANGED 409 One source exceeds the page budget.
RUN_RECORDING_WATERMARK_MISMATCH 409 A stream source recorded a position other than the one it was dispatched.

An author never sends these. They appear on a failed run’s record when Studio refused a worker’s callback. ATTEMPT_STALE, ATTEMPT_FENCE_STALE, ATTEMPT_SCOPE_MISMATCH, ARTIFACT_SESSION_EXPIRED, ARTIFACT_KIND_UNKNOWN, ARTIFACT_KIND_ALREADY_RESERVED, UPLOAD_SESSION_BINDING_MISMATCH, SESSION_NOT_FOUND, SESSION_EXPIRED, CREDENTIAL_HANDLE_UNKNOWN, CREDENTIAL_HANDLE_CONSUMED, CREDENTIAL_AUTHORITY_STALE, and the FETCH_* family.

Every other v4 code reaches the CLI verbatim as THIN_STUDIO_<CODE> with Studio’s own message. Studio bounds that message at 2000 characters.

These land on run.failure_code when a run fails. A run reports no code outside this list.

Code Meaning What the author does
ACQUISITION_FAILED the worker could not fetch a source read failure_detail. Check the address and the publisher
ACQUISITION_FORMAT_UNMAPPED the response media type maps to no data format pin a Reader whose accepted list carries it
ACQUISITION_CHILD_INVALID the confined acquisition child did not behave infrastructure. Report it
SOURCE_HTTP_5XX the publisher answered a server error retry later
SOURCE_RATE_LIMITED the publisher rate-limited the fetch raise min_interval_seconds, lower concurrency
SOURCE_PROXY_BUSY the egress proxy had no room retry
FETCH_AUTHORITY_UNAVAILABLE the worker could not resolve the credential authority check that the secret or connection remains enrolled
RUN_CREDENTIAL_SCOPE_INVALID the credential’s scope does not cover this source re-check credential on the source
COLLECTION_DISCOVERY_FAILED the publisher refused a first run’s listing request read the coverage block’s discovery_failure
COLLECTION_MERGE_INVALID the collection’s pages did not merge schemas differ between pages
PREDECESSOR_UNAVAILABLE the worker could not read the predecessor version the refresh has nothing to continue from
PREDECESSOR_HOST_REFUSED the predecessor’s host refused the read infrastructure
BOUNDED_DIRECT_ROUTE_REFUSED the bounded-direct path refused this run it falls back to batch
Code Meaning What the author does
CLAMP_EXCEEDED the run crossed a declared clamp raise --max-rows / --max-source-bytes, or narrow the window
CLAMP_UNSUPPORTED_FORMAT the clamp does not apply to this source. A document projection cannot run under a sample row clamp run the projection as a full source
RUN_CLAMPS_REQUIRED the mode needs a clamp and the run stated none pass one
RUN_CLAMPS_INVALID the clamps are not a legal set --max-rows, --max-source-bytes, --window
RUN_MODE_INVALID the mode does not fit this run check the mode against the table’s state
RUN_WINDOW_REQUIRED a backfill with no window pass --window START END
RUN_RECIPE_INVALID the job document’s recipe is not executable read failure_detail. It names the source and the reason
JOB_INVALID the async job block is not executable check generic_api.job
Code Meaning What the author does
TRANSFORM_STATEMENT_NOT_SELECT a step is not a single read-only SELECT rewrite the step
TRANSFORM_STATEMENT_NOT_SINGLE a step carries more than one statement split it into steps
TRANSFORM_STEP_DUPLICATE two steps share an id rename one
TRANSFORM_STEP_SHADOWS_SOURCE a step id collides with a source name rename the step
TRANSFORM_COLUMN_TYPE_MISMATCH the final SELECT returns a type the column declares otherwise cast(...) the column
TRANSFORM_PLAN_INVALID the plan is not a runnable graph check step order and references
TRANSFORM_ENGINE_UNCONFINED the worker could not confine the engine infrastructure
COLUMN_PRESENTATION_INCOMPATIBLE a chart does not describe that column type see Recipe document
Code Meaning What the author does
CHECK_FAILED a declared check with enforcement: required failed mr-data checks RUN_ID. Fix the recipe or accept the data
DECLARED_CHECK_INVALID a check is not a legal declaration see Checks
DECLARED_CHECK_COLUMN_UNKNOWN a check names a column the table does not have fix the name
DECLARED_CHECK_DUPLICATE two checks share an id rename one
DECLARED_CHECK_UNREADABLE the worker could not read a check fix the JSON
DECLARED_CHECKS_INVALID the checks block as a whole is not legal at most 128 checks
Code Meaning
WINDOW_UNRENDERABLE the address carries raw braces, or an undeclared placeholder. Window templates are path-only
WINDOW_FORMAT_UNSUPPORTED the source arrived in a format no window merges into
WINDOW_MERGE_INVALID the slice’s columns are not the columns the previous run wrote
WINDOW_PARTITION_UNREADABLE a row states no value in merge.partition.column that reads as a partition under the declared key
WINDOW_ROWS_OUT_OF_RANGE the source returned rows outside the requested window
WINDOW_SPAN_TOO_MANY_PARTITIONS the window covers more than 4096 partitions, which is what one merge may replace
SNAPSHOT_COLUMN_RESERVED the snapshot column name collides with a publisher column
SNAPSHOT_IDENTITY_INCOMPLETE merge.row_identity does not carry the snapshot column
SNAPSHOT_PARTITION_MISMATCH merge.partition is not the snapshot column with iso_date_value
SNAPSHOT_PARTITIONS_EXHAUSTED the merged relation would hold more days than max_partitions declares
SNAPSHOT_SPAN_FIXED a snapshot covers one day: granularity day, lookback_seconds 0, max_span_seconds 86400
SNAPSHOT_BEFORE_START_AT the worker read the source on a day before the snapshot’s start_at
SNAPSHOT_REQUEST_EXCLUSIVE the window states both request and snapshot
SNAPSHOT_SCOPES_UNSUPPORTED a snapshot window carries physical_scopes or bootstrap
SNAPSHOT_RELATION_EMPTY the fetch decoded to no rows, which is a fetch that returned nothing rather than a day with nothing in it
SNAPSHOT_RELATION_TOO_LARGE the merged relation is over 2 GiB
SNAPSHOT_RELATION_TRUNCATED a row clamp cut the fetch short, and a snapshot merge writes the whole of its day from that one slice
SOURCE_PHYSICAL_SCOPE_UNKNOWN a binding names a scope the run did not request
Code Meaning What the author does
ARTIFACT_PERSIST_FAILED the worker could not upload an artifact against Studio’s signed session retry the run
RUN_ARTIFACT_SESSION_INVALID the artifact session does not match what the worker reported retry the run
TABLE_PART_OVER_MAX one row group carried a part past the part byte ceiling narrow the window
TABLE_PART_MEMORY_CEILING the part sink was holding more bytes than its ceiling allows narrow the window
TABLE_PART_SCHEMA_DRIFT a new part’s schema differs from the version’s the recipe’s columns changed. Register a revision
TABLE_MANIFEST_INVALID the manifest does not describe the parts retry
TABLE_VERSION_UNCOMMITTABLE the worker could not commit the version retry
TABLE_UPSERT_UNCLUSTERED the upsert’s key range intersects too many predecessor parts use partition_replace, or cluster the table on its row_identity key
TABLE_FORMAT_UNSUPPORTED the table format is not one this worker writes worker and table disagree
TABLE_COMPACTION_INVALID the compaction request is not applicable read failure_detail
Code Raised by Meaning What the author does
EXECUTION_LOST Studio’s lease watchdog no worker holds this run any more: a crashed process, a preempted job, or an attempt that failed without reporting re-run it
EXECUTION_LEASE_EXPIRED Studio’s lease watchdog a worker still claims it and has stopped saying anything re-run it
WORKER_TERMINATED the worker something terminated the process re-run it
RUN_EXECUTION_FAILED the worker the execution failed with no narrower code read failure_detail
RUN_ATTEMPT_INVALID the worker the attempt identity did not check out retry
RUN_FENCE_INVALID the worker the fence generation did not check out retry
RUN_PREDECESSOR_INVALID the worker the predecessor document is not usable retry
RUN_RECORDING_INVALID the worker the named recording is not readable mr-data stream recordings --document-digest D
RUN_WATERMARK_INVALID the worker the stream watermark is not the one dispatched retry
CLAIM_KIND_UNKNOWN the worker the claim named a kind this worker does not run worker and Studio disagree

Cloud sits in front of Studio for token exchange and hosts the Public Dataset API. What each status means to the CLI:

Status Where Meaning What the author does
401 cloud or Studio cloud or Studio rejected the device credential or the token mr-data login
402 cloud the entitlement check refused the workspace has no hosted execution access
403 Studio the token does not carry this authority check the workspace role
409 Studio a state conflict, named by the v4 code read the code
412 Studio If-Match did not match re-read the resource and retry
413 cloud the artifact or result is too large narrow the query, or download Parquet
429 cloud or Studio rate limited honour Retry-After
503 cloud cloud’s Studio configuration is incomplete, or Studio stayed unavailable retry. The CLI retries a 503 that carries a retry window

Read the host first. mostlyright.md (and app., api.) is cloud. A …run.app host is Studio. In a CLI error, /api/auth/* and /api/cli/* are cloud, and /v4/* is Studio.

Read the error’s shape next. problem+json with schema_version: "4.0.0" and an x-correlation-id is Studio v4. {schema_version, error, request_id} is cloud’s Public API v2. A JSON-RPC error.code is cloud’s MCP. A bare THIN_* with no HTTP status is the CLI refusing locally.

Read the run record last. mr-data status RUN_ID --json carries failure_code, failure_detail and failed_stage. A stage from acquire, parse, transform, check, persist with a worker code points at the recipe or the publisher first. EXECUTION_LOST and EXECUTION_LEASE_EXPIRED point at the platform.

Fix a failed run walks the common ones. The numeric bounds behind CLAMP_EXCEEDED, READER_BUDGET and QUERY_TOO_MANY_PARTS are on Limits and ceilings.