coleam00/Archon · error · Error

Cannot generate dry-run stub for node '${node.id}': loop.unt

Error message

Cannot generate dry-run stub for node '${node.id}': loop.until_field requires an object-typed output_format

What it means

When a loop node uses loop.until_field, the dry-run stub generator sets that field to true in a synthesized object stub so the loop terminates in dry-run. This requires the output_format placeholder to be an object; if schemaPlaceholder produced a non-record value (scalar, array, etc.), the generator throws instead of mutating a non-object.

Source

Thrown at packages/workflows/src/dry-run.ts:173

    default:
      return 'TODO';
  }
}

function generatedStubFor(node: DagNode): DryRunStubValue {
  if (node.output_format === undefined) {
    return isLoopNode(node) && node.loop.until !== undefined ? node.loop.until : 'TODO';
  }
  if (node.output_format.$async === true) {
    throw new Error(
      `Cannot generate dry-run stub for node '${node.id}': asynchronous output_format schemas are unsupported`
    );
  }

  const value = schemaPlaceholder(node.output_format);
  if (isLoopNode(node) && node.loop.until_field !== undefined) {
    if (!isRecord(value)) {
      throw new Error(
        `Cannot generate dry-run stub for node '${node.id}': loop.until_field requires an object-typed output_format`
      );
    }
    value[node.loop.until_field] = true;
  }

  let compileError: string | undefined;
  const validation = validateStructuredOutput(value, node.output_format, message => {
    compileError = message;
  });
  if (compileError !== undefined) {
    throw new Error(
      `Cannot generate dry-run stub for node '${node.id}': output_format could not be compiled (${compileError})`
    );
  }
  if (!validation.valid) {
    throw new Error(
      `Cannot generate schema-valid dry-run stub for node '${node.id}': ${validation.errors.join('; ')}`

View on GitHub (pinned to 0773b97458)

Solutions

  1. Declare the loop node's output_format as type: object with the until_field as a boolean property
  2. Move loop.until_field onto a node whose output is genuinely an object
  3. If the loop checks a non-object output, switch the loop to a different until mechanism (e.g. loop.until expression evaluated on the value) that matches the output type
  4. Validate the workflow with the schema linter before dry-run to catch the type mismatch early

Example fix

// before
loop:
  until_field: done
output_format:
  type: string
// after
loop:
  until_field: done
output_format:
  type: object
  properties:
    done: { type: boolean }
    result: { type: string }
Defensive patterns

Strategy: validation

Validate before calling

if (isLoopNode(node) && node.loop.until_field !== undefined) {
  const stub = schemaPlaceholder(node.output_format);
  if (!isRecord(stub)) throw new Error(`node ${node.id}: until_field requires object output_format`);
}

Type guard

function isObjectOutputForUntilField(node: DagNode): boolean {
  if (!isLoopNode(node) || node.loop.until_field === undefined) return true;
  return node.output_format?.type === 'object';
}

Try / catch

try {
  await engine.dryRun(workflow);
} catch (err) {
  if (err instanceof Error && err.message.includes('requires an object-typed output_format')) {
    // change output_format to type: object with the until_field boolean property
  } else throw err;
}

Prevention

When it happens

Trigger: A loop node combines loop.until_field with an output_format whose placeholder is not an object — e.g. output_format type: string/number/array, or a schema whose generated placeholder fails isRecord — during dry-run stub generation.

Common situations: Writing loop.until_field against a loop node whose output_format declares a primitive or array type; forgetting that until_field addressing requires the node output to be an object; a schema typo (missing type: object) so the placeholder degrades to a scalar.

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


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