coleam00/Archon · error · Error
Workflow outcome_field '${field}' on returns node '${returns
Error message
Workflow outcome_field '${field}' on returns node '${returns}' did not resolve to a boolean What it means
Workflows may declare an outcome_field: the executor reads a boolean output field from the designated returns node after completion to classify the run as succeeded or failed. If the field cannot be resolved to an actual boolean value on that node's completed output, the executor throws rather than guessing the outcome.
Source
Thrown at packages/workflows/src/dag-executor.ts:11623
// Persist the authored verdict as soon as the selected result is available,
// independently from every lifecycle branch below (#2618). The initial call
// covers a selected node rehydrated from node_completed events on resume; the
// awaited per-layer hook captures a fresh result before later work can pause or
// fail; and the unwind backstop covers a fatal throw while aggregating that layer.
// A same-value write is skipped, but a genuine re-execution may replace the
// prior verdict.
let persistedOutcome: WorkflowRunOutcome | null = workflowRun.outcome;
const persistAuthoredOutcome = async (): Promise<void> => {
const field = workflow.outcome_field;
const returns = workflow.returns;
if (field === undefined || returns === undefined) return;
const selectedOutput = nodeOutputs.get(returns);
if (selectedOutput?.state !== 'completed') return;
const resolution = resolveNodeOutputField(selectedOutput, returns, field);
if (resolution.kind !== 'value' || typeof resolution.value !== 'boolean') {
throw new Error(
`Workflow outcome_field '${field}' on returns node '${returns}' did not resolve to a boolean`
);
}
const outcome: WorkflowRunOutcome = resolution.value ? 'succeeded' : 'failed';
if (outcome === persistedOutcome) return;
await deps.store.updateWorkflowRun(workflowRun.id, { outcome });
persistedOutcome = outcome;
};
// Run the topological layers. runLayers mutates the context's mutable fields in place
// (nodeOutputs, lastSequentialSession, usage accumulators); we read them back below
// for the terminal tally. stepNamePrefix is '' for the top-level DAG so node event
// step_names are the raw node ids (identical to pre-refactor behavior). Fields stay
// explicit because spreading options would also copy executor-only state into this
// context without an excess-property check.
const runCtx: RunLayersContext = {
deps,
platform,View on GitHub (pinned to 0773b97458)
Solutions
- Make the output_format declare outcome_field as type: boolean and verify the node's actual output matches
- Fix the field path/name to match the returns node's output structure exactly
- Add a coercion or normalization step: have the returns node emit a strict boolean (e.g. via output_format constraints) rather than a string
- Update outcome_field to point at the correct returns node id if the graph was refactored
Example fix
// before
returns: publish
outcome_field: was_successful # not in schema / string
output_format:
type: object
properties:
was_successful: { type: string }
// after
output_format:
type: object
properties:
was_successful: { type: boolean } Defensive patterns
Strategy: type-guard
Validate before calling
const out = nodeOutputs.get(returnsNodeId);
if (out?.state === 'completed') {
const v = resolveNodeOutputField(out, returnsNodeId, outcomeField);
if (v.kind !== 'value' || typeof v.value !== 'boolean') throw new Error('outcome_field must resolve to a boolean');
} Type guard
function isBooleanResolution(r: Resolution): r is { kind: 'value'; value: boolean } {
return r.kind === 'value' && typeof r.value === 'boolean';
} Try / catch
try {
await engine.run(workflow);
} catch (err) {
if (err instanceof Error && err.message.includes('did not resolve to a boolean')) {
// fix outcome_field path or coerce the node output to a strict boolean
} else throw err;
} Prevention
- Declare outcome_field as type: boolean in the returns node's output_format
- Keep outcome_field in sync with the output schema; update both together
- Prompt for strict booleans (avoid "true" strings) when the field classifies the run
When it happens
Trigger: The returns node completed but its output_format produces a non-boolean for outcome_field: field missing, nested under a different path, typed string/number, or $async resolution returned something other than a concrete boolean value.
Common situations: Typos in the field name versus output_format schema; schema says boolean but a prompt returned a string like "true"; output_format changed after the outcome_field was written; returns node id renamed so nodeOutputs holds a different node's data.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Workflow '${workflow.name}' sets worktree.enabled: false (ru
- Workflow '${workflow.name}' sets worktree.enabled: false (ru
- Workflow '${workflow.name}' sets worktree.enabled: false (ru
- Workflow '${workflow.name}' sets worktree.enabled: true (req
- Node '${node.id}': output_format declared but the provider's
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/5deb5091fb5cfd38.
Report an issue: GitHub.