coleam00/Archon · error · OutputRefError
producer-failed
producer-failed
Error message
producer-failed
What it means
A producer node whose state is `failed` never resolves a `$node.field` reference, even if its leftover output text looks like valid JSON. This is deliberate (#2713): loop_group failure paths carry the last completed iteration's real JSON, which would otherwise be silently consumed as if the group had succeeded.
Source
Thrown at packages/workflows/src/output-ref.ts:351
nodeOutput: NodeOutput,
nodeId: string,
field: string
): FieldResolution {
// A producer that did not run (skipped) or has not settled (pending) has no
// output to read a field from. Surface that directly rather than letting it
// fall through to the schemaless path and throw the misleading "not a JSON
// object" error on its empty output.
if (nodeOutput.state === 'skipped' || nodeOutput.state === 'pending') {
throw new OutputRefError(nodeId, field, 'producer-not-run');
}
// A failed producer never resolves a field, however JSON-shaped its leftover
// output looks (#2713): a loop_group's failure paths carry the last completed
// iteration's real, often-valid-JSON text, which would otherwise be read here
// as if the group had succeeded — the same class of bug #2696/#2710 fixed for
// the `{ from, if_skipped }` binding directive.
if (nodeOutput.state === 'failed') {
throw new OutputRefError(nodeId, field, 'producer-failed');
}
const declaredFields = 'declaredFields' in nodeOutput ? nodeOutput.declaredFields : undefined;
const structured = 'structuredOutput' in nodeOutput ? nodeOutput.structuredOutput : undefined;
const structuredObj = asPlainObject(structured);
// 1. Declared-schema producer — the declared property set IS the contract.
if (declaredFields !== undefined) {
if (!declaredFields.includes(field)) {
throw new OutputRefError(nodeId, field, 'not-in-schema');
}
// Prefer the parsed payload; fall back to parsing the JSON-serialized output.
// The fallback covers older NodeOutput rows that predate `structuredOutput`,
// and resumes of runs persisted before `structured_output` rode along in
// `node_completed` events (#2637) — current resumes rehydrate the payload.
const obj = structuredObj ?? parseOutputObject(nodeOutput.output);
// No parseable object AT ALL is not a declared-optional field — it is a producer
// that did not honour its schema, and it must fail exactly as loudly as theView on GitHub (pinned to 0773b97458)
Solutions
- Add retry/backoff on the producer node (`retry:`) so transient failures do not propagate.
- Add an `on_error`/fallback path or `{ from, if_failed }` style handling on the consumer so it degrades explicitly.
- Fix the root cause of the producer failure (inspect its error in run output).
- Guard the consumer with a condition so it does not run when the producer failed.
Example fix
// before
- id: summarize
prompt: ...
- id: notify
bash: echo "$summarize.text"
// after
- id: summarize
prompt: ...
retry: {max_attempts: 3}
on_error: continue
- id: notify
bash: echo "${summarize.text:-summary unavailable}" Defensive patterns
Strategy: try-catch
Validate before calling
const o = run.nodeOutputs[producerId];
if (o?.state === 'failed') {
// do not read $producer.field — leftover output is not trustworthy
takeFailurePath(producerId);
} Type guard
function producerSucceeded(o: { state: string } | undefined): boolean {
return o?.state === 'succeeded';
} Try / catch
try {
const value = resolveNodeOutputField(nodeOutput, nodeId, field);
} catch (err) {
if (err instanceof OutputRefError && err.reason === 'producer-failed') {
log.warn(`Producer ${nodeId} failed; using fallback for '${field}'`);
return fallbackValue(field);
}
throw err;
} Prevention
- Add `retry:` with backoff on flaky AI/bash producers so failures are absorbed upstream.
- Use `on_error: continue` plus explicit fallback bindings on consumers.
- Never parse a failed node's leftover output yourself — the engine blocks it deliberately (#2713).
- Check node state before reading any `$node.field` in custom tooling.
When it happens
Trigger: A consumer references `$producer.field` and the producer node ended in `failed` state, leaving behind a partially-written or last-iteration output string.
Common situations: Reading a field from a failed AI node without a retry; loop_group whose final iteration failed after earlier successful ones; missing error handling (`on_error`, fallback bindings) upstream of the consumer.
Related errors
- producer-not-run
- not-in-schema
- unparseableReason(nodeOutput.output) (dynamic reason code fo
- missing-key
- Cannot execute run '${detachedPreCreatedRun.id}': it belongs
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/e5d7ae722e88aa59.
Report an issue: GitHub.