coleam00/Archon · error · Error

Workflow run has invalid effective model bindings.

Error message

Workflow run has invalid effective model bindings.

What it means

readRunModelBindingsMetadata also validates the 'effective' section of model_bindings metadata (the resolved bindings actually used for execution). If safeParse fails with a path rooted at 'effective', it throws this error. Effective bindings are recomputed-but-persisted state; if they are invalid, the run record is internally inconsistent and execution refuses to proceed rather than trusting corrupt data.

Solutions

  1. Recompute and rewrite the effective bindings section (or delete the run and start a new one) so it matches the schema
  2. Resume from a run whose metadata was written by a compatible writer version
  3. Fix the writer that persists effective bindings to conform to runModelBindingsMetadataSchema

Example fix

// before
"effective": { "node1": "gpt-4o-mini" }
// after
"effective": { "node1": { "model": "gpt-4o-mini" } }
Defensive patterns

Strategy: try-catch

Validate before calling

const parsed = runModelBindingsMetadataSchema.safeParse(metadata);
if (!parsed.success) {
  if (parsed.error.issues.some(i => i.path[0] === 'effective')) {
    throw new Error('Workflow run has invalid effective model bindings.');
  }
}

Type guard

function hasValidEffectiveBindings(m: { effective?: unknown }): boolean {
  return runModelBindingsMetadataSchema.pick({ effective: true }).safeParse({ effective: m.effective }).success;
}

Try / catch

try {
  await executeWorkflow(runId);
} catch (err) {
  if (err instanceof Error && err.message === 'Workflow run has invalid effective model bindings.') {
    console.error('Persisted effective bindings are corrupt; recompute them or start a new run.');
  } else throw err;
}

Prevention

When it happens

Trigger: executeWorkflow reads a run whose persisted effective bindings section fails runModelBindingsMetadataSchema — e.g. malformed binding entries under effective/ written by a buggy or older writer, or manual database tampering.

Common situations: Version drift between the binary that wrote the run and the binary resuming it; a writer bug persisting effective bindings before overrides were normalized; manual edits to run rows.

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/4d87e70f68f7cf3e. Report an issue: GitHub.

Appendix: source

Thrown at packages/workflows/src/model-validation.ts:510

  metadata: Record<string, unknown> | undefined
): RunModelBindingsMetadata | undefined {
  const value = metadata?.[RUN_MODEL_BINDINGS_METADATA_KEY];
  if (value === undefined) return undefined;
  const parsed = runModelBindingsMetadataSchema.safeParse(value);
  if (!parsed.success) {
    const path = parsed.error.issues[0]?.path ?? [];
    const bindingName = typeof path[2] === 'string' ? path[2] : 'unknown';
    if (path.includes('thinking')) {
      throw new Error(`Model binding '${bindingName}' has invalid thinking options.`);
    }
    if (path.includes('effort')) {
      throw new Error(`Model binding '${bindingName}' has an invalid effort.`);
    }
    if (path[0] === 'overrides' && (path[1] === 'tiers' || path[1] === 'aliases')) {
      throw new Error(`Workflow run has invalid model_bindings ${path[1]} metadata.`);
    }
    if (path[0] === 'effective') {
      throw new Error('Workflow run has invalid effective model bindings.');
    }
    throw new Error('Workflow run has invalid model_bindings metadata.');
  }

  const tiers = Object.fromEntries(
    Object.entries(parsed.data.overrides.tiers ?? {}).map(([name, preset]) => [
      name,
      normalizePersistedOverridePreset(name, preset),
    ])
  );
  const aliases = Object.fromEntries(
    Object.entries(parsed.data.overrides.aliases ?? {}).map(([name, preset]) => [
      name,
      normalizePersistedOverridePreset(name, preset),
    ])
  );
  for (const [name, preset] of Object.entries(parsed.data.effective.aliases)) {
    assertValidPersistedPreset(name, preset);

View on GitHub (pinned to 0773b97458)