coleam00/Archon · error · Error

Cannot execute run '${detachedPreCreatedRun.id}': it belongs

Error message

Cannot execute run '${detachedPreCreatedRun.id}': it belongs to workflow '${detachedPreCreatedRun.workflow_name}', not '${workflow.name}'.

What it means

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.

Source

Thrown at packages/cli/src/commands/workflow.ts:1656

    );
    if (loadError) {
      throw new Error(
        `Workflow '${workflowName}' failed to load: ${loadError.error}\n\nFix the YAML file and try again.`
      );
    }
    const availableWorkflows = workflows.map(w => `  - ${w.name}`).join('\n');
    throw new Error(
      `Workflow '${workflowName}' not found.\n\nAvailable workflows:\n${availableWorkflows}`
    );
  }

  // Second half of the handed-over row's claim check (#2872): the row must belong to the
  // workflow being invoked. Checked here rather than at load because the row carries the
  // RESOLVED name its launcher selected, and resolution needs discovery. It catches an
  // id crossed between two concurrent detached launches, and the narrow window where the
  // child's re-capture resolves a different workflow than the parent did.
  if (detachedPreCreatedRun && detachedPreCreatedRun.workflow_name !== workflow.name) {
    throw new Error(
      `Cannot execute run '${detachedPreCreatedRun.id}': it belongs to workflow ` +
        `'${detachedPreCreatedRun.workflow_name}', not '${workflow.name}'.`
    );
  }

  // Keys this workflow's YAML declares that the engine drops (#2213). Written to
  // stderr, never stdout: in --json mode Pino is silenced and stdout must stay
  // exactly the machine-readable payload, so this is the ONLY channel that
  // reaches an agent driving runs through `--json`. Not gated on --quiet — a
  // dropped key can be a gate the author believes is protecting the run.
  emitParseWarnings(workflowEntry?.parseWarnings, workflow.name);
  emitDeprecationNotice(workflow);

  if (isContinuation && options.modelAssignments && options.modelAssignments.length > 0) {
    throw new Error(
      '--resume and --model are mutually exclusive. A resumed run keeps its original model bindings.'
    );
  }

View on GitHub (pinned to 0773b97458)

Solutions

  1. Confirm the run id belongs to the workflow you invoked (`archon workflow runs` or inspect the run row)
  2. Cancel/abandon the crossed run row and start a fresh detached launch
  3. Re-run with the workflow name recorded in the run row

Example fix

// before
archon workflow run other-workflow --resume <run-id-created-for-workflow-a>
// after
archon workflow run workflow-a --resume <run-id-created-for-workflow-a>
Defensive patterns

Strategy: validation

Validate before calling

const run = await getRun(runId);
if (run.workflow_name !== workflowName) {
  throw new Error(`Run ${runId} belongs to '${run.workflow_name}', not '${workflowName}'`);
}

Try / catch

try {
  await archon.workflow.run(name, { resume: runId });
} catch (e) {
  if (/it belongs to workflow/.test(String(e.message))) {
    const owner = String(e.message).match(/belongs to workflow '(.*?)'/)?.[1];
    console.error(`Resume with workflow '${owner}'`);
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: Scripting parallel detached runs and reusing a stale run id; resuming a run after the workflow YAML's name changed between launches.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/b3164eff8d13d591. Report an issue: GitHub.