{"record":{"id":"b3164eff8d13d591","repo":"coleam00/Archon","slug":"cannot-execute-run-detachedprecreatedrun-id-b3164e","errorCode":null,"errorMessage":"Cannot execute run '${detachedPreCreatedRun.id}': it belongs to workflow '${detachedPreCreatedRun.workflow_name}', not '${workflow.name}'.","messagePattern":"Cannot execute run '(.+?)': it belongs to workflow '(.+?)', not '(.+?)'\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/workflow.ts","lineNumber":1656,"sourceCode":"    );\n    if (loadError) {\n      throw new Error(\n        `Workflow '${workflowName}' failed to load: ${loadError.error}\\n\\nFix the YAML file and try again.`\n      );\n    }\n    const availableWorkflows = workflows.map(w => `  - ${w.name}`).join('\\n');\n    throw new Error(\n      `Workflow '${workflowName}' not found.\\n\\nAvailable workflows:\\n${availableWorkflows}`\n    );\n  }\n\n  // Second half of the handed-over row's claim check (#2872): the row must belong to the\n  // workflow being invoked. Checked here rather than at load because the row carries the\n  // RESOLVED name its launcher selected, and resolution needs discovery. It catches an\n  // id crossed between two concurrent detached launches, and the narrow window where the\n  // child's re-capture resolves a different workflow than the parent did.\n  if (detachedPreCreatedRun && detachedPreCreatedRun.workflow_name !== workflow.name) {\n    throw new Error(\n      `Cannot execute run '${detachedPreCreatedRun.id}': it belongs to workflow ` +\n        `'${detachedPreCreatedRun.workflow_name}', not '${workflow.name}'.`\n    );\n  }\n\n  // Keys this workflow's YAML declares that the engine drops (#2213). Written to\n  // stderr, never stdout: in --json mode Pino is silenced and stdout must stay\n  // exactly the machine-readable payload, so this is the ONLY channel that\n  // reaches an agent driving runs through `--json`. Not gated on --quiet — a\n  // dropped key can be a gate the author believes is protecting the run.\n  emitParseWarnings(workflowEntry?.parseWarnings, workflow.name);\n  emitDeprecationNotice(workflow);\n\n  if (isContinuation && options.modelAssignments && options.modelAssignments.length > 0) {\n    throw new Error(\n      '--resume and --model are mutually exclusive. A resumed run keeps its original model bindings.'\n    );\n  }","sourceCodeStart":1638,"sourceCodeEnd":1674,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/cli/src/commands/workflow.ts#L1638-L1674","documentation":"Guard for a pre-created detached run row (#2872): when executing a hand-over run row, the row's `workflow_name` must match the workflow resolved by this invocation. The check lives after discovery because the row stores the RESOLVED name. It catches a run id crossed between two concurrent detached launches, or a child re-capture resolving a different workflow.","triggerScenarios":"Two concurrent detached launches crossing ids; passing a run id to resume/execute that was created for a different workflow; a race where the child re-captures a different workflow than the parent resolved.","commonSituations":"Scripting parallel detached runs and reusing a stale run id; resuming a run after the workflow YAML's name changed between launches.","solutions":["Confirm the run id belongs to the workflow you invoked (`archon workflow runs` or inspect the run row)","Cancel/abandon the crossed run row and start a fresh detached launch","Re-run with the workflow name recorded in the run row"],"exampleFix":"// before\narchon workflow run other-workflow --resume <run-id-created-for-workflow-a>\n// after\narchon workflow run workflow-a --resume <run-id-created-for-workflow-a>","handlingStrategy":"validation","validationCode":"const run = await getRun(runId);\nif (run.workflow_name !== workflowName) {\n  throw new Error(`Run ${runId} belongs to '${run.workflow_name}', not '${workflowName}'`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await archon.workflow.run(name, { resume: runId });\n} catch (e) {\n  if (/it belongs to workflow/.test(String(e.message))) {\n    const owner = String(e.message).match(/belongs to workflow '(.*?)'/)?.[1];\n    console.error(`Resume with workflow '${owner}'`);\n  } else throw e;\n}","preventionTips":["Serialize detached launches; never hand over the same run id to concurrent processes","Store the owning workflow name alongside any run id you persist","Re-resume with the exact workflow recorded in the run row"],"tags":["cli","workflow","race-condition","run-id"],"backgroundTag":"run-workflow-mismatch","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}