shareAI-lab/learn-claude-code · error · WorkflowInputError
agent({{schema}}) invalid output: {err}
Error message
agent({{schema}}) invalid output: {err} What it means
When agent() is called with a schema, the runner is forced into StructuredOutput mode and the result is validated with SimpleJsonSchema. On the first failure the model is retried once with 'Return valid JSON.' appended; if the retry also fails validation, WorkflowInputError with the schema error text is raised. Nothing is journaled for the failed call, so a later retry re-runs the agent from scratch.
Source
Thrown at s16_workflow_runtime/code.py:496
self.runner.run, prompt, schema, label
)
result = run.value
tokens = run.tokens
if schema is not None:
ok, err = SimpleJsonSchema(schema).validate(result)
if not ok:
retry = await asyncio.to_thread(
self.runner.run,
prompt + "\n\nReturn valid JSON.",
schema,
label,
)
result = retry.value
tokens += retry.tokens
ok, err = SimpleJsonSchema(schema).validate(result)
if not ok:
raise WorkflowInputError(f"agent({{schema}}) invalid output: {err}")
self.budget.add(tokens)
self.task.usage["agents"] += 1
self.task.usage["tokens"] += tokens
self.journal.record(key, result)
self.task.progress_event("workflow_agent", label=label,
phase=phase or self._phase, status="done")
return result
async def parallel(self, thunks):
"""BARRIER: run all thunks concurrently and fail if any thunk fails."""
return await asyncio.gather(*[thunk() for thunk in thunks])
async def pipeline(self, items, *stages):
"""Per-item staged flow, NO barrier between stages: item A can be in
stage 3 while item B is still in stage 1. Each stage gets
(prev_result, original_item, index). A throwing stage fails the workflow."""
async def run_item(item, idx):View on GitHub (pinned to 985456f4ad)
Solutions
- Simplify the schema: fewer required fields, flatter structure, relax types (e.g. accept string|number), allow additional properties.
- Make the prompt explicitly request every required field with the exact names and types the schema expects.
- Increase the runner's max output tokens so the JSON is not truncated.
- Re-run the workflow — the failed attempt was not journaled, so the agent gets two fresh attempts under the improved schema.
Example fix
# before
schema = {"type": "object", "required": ["findings", "severity", "citations"],
"additionalProperties": False}
# after
schema = {"type": "object", "required": ["findings"],
"properties": {"findings": {"type": "array"}}} Defensive patterns
Strategy: retry
Validate before calling
from s16_workflow_runtime import SimpleJsonSchema
def schema_is_model_feasible(schema) -> bool:
# cheap sanity: object root, <= 5 required keys, no deep nesting
props = schema.get("properties", {})
req = schema.get("required", [])
return schema.get("type") == "object" and len(req) <= 5 and len(props) <= 10 Try / catch
last = None
for attempt in range(3):
try:
return await ctx.agent(prompt, schema=S, label=lbl)
except WorkflowInputError as e:
if "invalid output" not in str(e):
raise
last = e
prompt += "\nRespond ONLY with JSON matching: " + json.dumps(S)
raise last Prevention
- Keep schemas flat with few required fields; make optional what the model may omit.
- Spell out every required field name and type in the prompt itself.
- Raise the runner's max output tokens so JSON never truncates.
When it happens
Trigger: ctx.agent(prompt, schema=...) where the model returns JSON that violates the schema twice in a row — e.g. missing required fields, wrong types, extra fields when additionalProperties is false, or truncated output.
Common situations: Overly strict or nested schemas the model can't satisfy; required fields the prompt never asks for; long outputs hitting max tokens and truncating the JSON; weak models on structured output.
Related errors
- cached agent output failed schema validation: {err}
- memory store is too large for one consolidation pass
- consolidation returned empty or duplicate records
- Max retries ({MAX_RETRIES}) exceeded
- could not allocate a unique workflow runId
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/1c9e56eae2608715.
Report an issue: GitHub.