coleam00/Archon · error · Error

Invalid dry-run stub file '${path}': contains the fixture ke

Error message

Invalid dry-run stub file '${path}': contains the fixture key '${reservedHit}' — this is a fixture file; run it with 'workflow test'

What it means

Thrown by loadDryRunStubs when the stub mapping contains a key in RESERVED_FIXTURE_KEYS — the file is a test fixture, not a stub file. The engine refuses to interpret fixture-shaped files as stubs and points the user to `workflow test`, the command that understands fixture keys.

Source

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

  }

  let parsed: unknown;
  try {
    parsed = Bun.YAML.parse(await file.text());
  } catch (error) {
    throw new Error(`Failed to parse dry-run stub file '${path}': ${(error as Error).message}`);
  }

  if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
    throw new Error(
      `Invalid dry-run stub file '${path}': expected one YAML mapping of node ids to outputs`
    );
  }
  const reservedHit = Object.keys(parsed as Record<string, unknown>).find(key =>
    RESERVED_FIXTURE_KEYS.has(key)
  );
  if (reservedHit !== undefined) {
    throw new Error(
      `Invalid dry-run stub file '${path}': contains the fixture key '${reservedHit}' — this is a fixture file; run it with 'workflow test'`
    );
  }
  const result = dryRunStubsSchema.safeParse(parsed);
  if (!result.success) {
    const issues = result.error.issues
      .map(issue => `${issue.path.join('.') || '<root>'}: ${issue.message}`)
      .join('; ');
    throw new Error(`Invalid dry-run stub file '${path}': ${issues}`);
  }
  return result.data;
}

function nodeType(node: DagNode): z.infer<typeof dryRunNodeTypeSchema> {
  // `include:` is no longer a DagNode member (#2486) — it never reaches this function.
  if (isAgentNode(node) && node.source.kind === 'command') return 'command';
  if (isExecNode(node)) return node.runtime === 'sh' ? 'bash' : 'script';
  if (isLoopNode(node)) return 'loop';

View on GitHub (pinned to 0773b97458)

Solutions

  1. Run the file through `workflow test` instead — it is a fixture file, as the message says.
  2. Remove the reserved fixture key from the YAML if it was added by mistake.
  3. Use separate paths for fixtures and stubs to avoid passing the wrong file.

Example fix

# before (fixture key in stub file)
fixtures:
  summarize: { text: hi }
# after
summarize:
  text: hi
Defensive patterns

Strategy: validation

Validate before calling

const RESERVED_FIXTURE_KEYS = new Set(["fixtures", "inputs"]); // mirror engine's set
function stubFileHasNoFixtureKeys(keys: string[]): string | undefined {
  return keys.find(k => RESERVED_FIXTURE_KEYS.has(k));
}

Type guard

function isPlainStubMapping(v: Record<string, unknown>): boolean {
  return !Object.keys(v).some(k => RESERVED_FIXTURE_KEYS.has(k));
}

Try / catch

try {
  const stubs = await loadDryRunStubs(path);
} catch (err) {
  if (err instanceof Error && err.message.includes("this is a fixture file")) {
    console.error("Wrong file type: run fixtures with 'workflow test', not as dry-run stubs.");
  } else throw err;
}

Prevention

When it happens

Trigger: Loading a stub file that contains fixture-reserved top-level keys (e.g. keys like `fixtures` / `inputs` used by the fixture format) — typically by passing a fixture file where a stub file is expected.

Common situations: Mixing up the fixture file produced for `workflow test` with the dry-run stub file, or hand-editing a stub and accidentally adding a reserved fixture key.

Related errors


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