coleam00/Archon · error

Node '${consumerId}' binding '${name}': an object value must

Error message

Node '${consumerId}' binding '${name}': an object value must be a binding directive { from: '$node.output[.field]', if_skipped?: <value> }. Use a string, number, boolean, null, or array for a literal value.

What it means

resolveNodeBindings accepts either a plain literal value or an explicit binding directive object { from, if_skipped? } for each with: entry. A plain object that is neither (a binding directive shape was not recognized) is rejected. The YAML loader normally rejects this at load time, but programmatic workflow definitions can reach the executor, so the failure is kept loud and actionable.

Source

Thrown at packages/workflows/src/dag-executor.ts:456

 * for that simulator only; it must resolve bindings with THIS function so preview
 * and execution cannot drift (#2637 R2).
 */
export function resolveNodeBindings(
  consumerId: string,
  withMap: Record<string, JsonValue | BindingDirective>,
  ctx: ShellInputContext,
  runInputs: Record<string, JsonValue> | undefined
): Record<string, JsonValue> {
  const resolved: Record<string, JsonValue> = {};
  for (const [name, rawValue] of Object.entries(withMap)) {
    if (isBindingDirective(rawValue)) {
      resolved[name] = resolveBindingDirective(consumerId, name, rawValue, ctx);
      continue;
    }
    if (typeof rawValue === 'object' && rawValue !== null && !Array.isArray(rawValue)) {
      // The loader rejects this shape at load time; programmatic definitions can
      // still reach here, so keep the failure loud and actionable.
      throw new Error(
        `Node '${consumerId}' binding '${name}': an object value must be a binding directive ` +
          "{ from: '$node.output[.field]', if_skipped?: <value> }. Use a string, number, " +
          'boolean, null, or array for a literal value.'
      );
    }
    resolved[name] = resolveWorkflowValue(rawValue, ctx, runInputs, true);
  }
  return resolved;
}

function resolveBindingDirective(
  consumerId: string,
  name: string,
  directive: BindingDirective,
  ctx: ShellInputContext
): JsonValue {
  const ref = parseWholeOutputRef(directive.from);
  if (ref === undefined) {

View on GitHub (pinned to 0773b97458)

Solutions

  1. Wrap the object in a binding directive: { from: '$node.output[.field]', if_skipped?: <value> }.
  2. Replace the object with a literal (string, number, boolean, null, or array) if a static value is intended.
  3. Validate the definition through the loader before execution so the error surfaces at load time with richer context.

Example fix

// before
with:
  config:
    model: fast
    prompt: hello
// after
with:
  config: '{"model":"fast","prompt":"hello"}'   # literal, or:
  config:
    from: '$build_config.output'
Defensive patterns

Strategy: validation

Validate before calling

function isBindingDirective(v: unknown): boolean {
  return typeof v === 'object' && v !== null && !Array.isArray(v) && 'from' in v;
}
function validateWithValue(v: unknown): string | null {
  if (typeof v === 'object' && v !== null && !Array.isArray(v) && !isBindingDirective(v))
    return 'Object with: values must be { from: ... } directives or literals';
  return null;
}

Type guard

function isBindingDirective(v: unknown): v is { from: string; if_skipped?: unknown } {
  return typeof v === 'object' && v !== null && !Array.isArray(v) && typeof (v as any).from === 'string';
}

Try / catch

try {
  runWorkflow(wf);
} catch (e) {
  if (e instanceof Error && e.message.includes('must be a binding directive')) {
    console.error('Invalid with: value shape — use { from } or a literal:', e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a Record/object as a with: value through a programmatically constructed workflow definition (API or code that builds the withMap) where the object lacks the recognized 'from' key or directive shape.

Common situations: Building workflow JSON in TypeScript and nesting a config object (e.g. { model: ..., prompt: ... }) as a binding value expecting it to pass through; typos like 'from_' or 'source:' instead of 'from:'; loader bypass in tests or the dry-run simulator path.

Related errors


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