coleam00/Archon · error · WorkflowAdoptionError
Cannot adopt run '${options.adoptRunId}': this conversation
Error message
Cannot adopt run '${options.adoptRunId}': this conversation already continues run '${resumableRun.id}' (${resumableRun.status}). Resume or abandon that run first, or declare the adoption from a conversation with no open run. What it means
WorkflowAdoptionError thrown when a dispatch both requests adoption of a run (adoptRunId) and would naturally continue an existing resumable run in the same conversation. Adoption and continuation are mutually exclusive — both decide where the run executes and which estate it inherits — so the combination is rejected up front instead of silently dropping the adopted id.
Source
Thrown at packages/core/src/orchestrator/orchestrator-agent.ts:872
// It does NOT mirror the other refusal exit below — an explicit resume naming a run
// with no `working_path` is now preempted by the gate instead of reaching that check.
// That is a behaviour change and it is deliberate. Every row-creation site records a
// real `working_path`, so a NULL one means a row predating the column; reaching the
// gate with a violation to defer additionally needs that ancient run's workflow to
// have since gained a required input, and someone to resume it explicitly. (The gate
// judges the CURRENT YAML, not the row's vintage, so that combination is improbable
// rather than impossible.) Both exits refuse at zero cost, so which message wins is a
// wording question, not a correctness one.
const willContinueExistingRun =
Boolean(resumableRun?.working_path) &&
(resumableRun?.status === 'paused' || resumableRun?.id === options?.resumeRunId);
// Adoption and continuation are mutually exclusive: both decide where the run
// executes and which estate it inherits, and every continuation path below forwards
// only the resume context — an adopted id would be validated above and then silently
// dropped. Refuse the combination up front, mirroring the CLI's adopt/resume guard.
if (options?.adoptRunId !== undefined && willContinueExistingRun && resumableRun) {
throw new WorkflowAdoptionError(
`Cannot adopt run '${options.adoptRunId}': this conversation already continues ` +
`run '${resumableRun.id}' (${resumableRun.status}). Resume or abandon that run ` +
'first, or declare the adoption from a conversation with no open run.'
);
}
// ── Executable source ───────────────────────────────────────────────────────
//
// AFTER resume detection, on purpose. A continuation must execute the source its run
// already froze; capturing here would freeze current bytes, re-resolve the graph from
// them, and then hand the executor a run whose recorded capture supplies the commands
// and scripts — a graph from one moment against resources from another. Capturing a
// resume also leaves a staging directory nothing adopts.
//
// For a fresh run: freeze, then re-resolve the workflow FROM the frozen copy, so the
// definition executed and the resources beside it are one consistent set of bytes.
const runCwd = conversation.cwd ?? codebase.default_cwd;
// `preparedSource` is the outer binding the resume branch reads (always undefinedView on GitHub (pinned to 0773b97458)
Solutions
- Resume or abandon the conversation's existing resumable run first, then retry the adoption.
- Remove adoptRunId and let the dispatch continue the existing run.
- Start the adoption from a different conversation (or a new one) that has no open run.
Example fix
// before
await dispatchOrchestratorWorkflow({ conversationId, adoptRunId: 'run-b' }); // conversation continues 'run-a'
// after
await resumeOrAbandonRun('run-a');
await dispatchOrchestratorWorkflow({ conversationId, adoptRunId: 'run-b' }); Defensive patterns
Strategy: validation
Validate before calling
const open = await getResumableRunForConversation(conversationId);
if (adoptRunId && open) throw new Error(`Conversation already continues ${open.id}; resolve it before adopting`); Try / catch
try {
await dispatchOrchestratorWorkflow({ conversationId, adoptRunId });
} catch (e) {
if (e instanceof WorkflowAdoptionError && e.message.includes('already continues run')) {
await resumeOrAbandonExistingRun(conversationId);
await dispatchOrchestratorWorkflow({ conversationId, adoptRunId });
} else throw e;
} Prevention
- Never set adoptRunId on dispatches into a conversation with an open run.
- Check conversation run state before sending adopt-style commands.
- Prefer resume for continuing the same conversation's run; use adoption only from clean conversations.
When it happens
Trigger: Calling dispatchOrchestratorWorkflow with options.adoptRunId in a conversation whose state already yields a resumable run (willContinueExistingRun && resumableRun), e.g. sending a follow-up message that says 'adopt run X' while the conversation is mid-continuation of run Y.
Common situations: A user pastes an adopt command into a conversation that already has an open run; an automation sets adoptRunId unconditionally while the session state also carries a resumable run; mixing the CLI's resume flow with an adopt flag.
Related errors
- Workflow run '${resolvedId}' has no working path recorded. C
- Failed to resume workflow '${run.workflow_name}': ${err.mess
- Approved but failed to resume workflow '${result.workflowNam
- Rejected but failed to resume workflow '${result.workflowNam
- Response recorded but failed to resume workflow '${result.wo
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/c493e457a1b266ed.
Report an issue: GitHub.