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 the

View on GitHub (pinned to 0773b97458)

Solutions

  1. Add retry/backoff on the producer node (`retry:`) so transient failures do not propagate.
  2. Add an `on_error`/fallback path or `{ from, if_failed }` style handling on the consumer so it degrades explicitly.
  3. Fix the root cause of the producer failure (inspect its error in run output).
  4. 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

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


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