Skip to content

[BUG] StructuredOutput tool wraps data in 'output' field causing schema validation to fail #502

Description

@AgentWrapper

Bug Description

When using structured outputs with output_format, the StructuredOutput tool intermittently wraps user data in an {"output": {...}} field. Validation fails when the wrapper is present.

This is non-deterministic - same prompt can produce either format:

// Sometimes (works):
{"actions": [...]}

// Sometimes (fails validation):
{"output": {"actions": [...]}}

Impact

  1. ResultMessage.structured_output is None when wrapper is present
  2. Agent confusion - Claude sees conflicting validation errors and may simplify output (e.g., 47 items → 1 item)
  3. Flaky results - identical prompts succeed or fail randomly

Tool Response Error

Output does not match required schema: root: must have required property 'actions', root: must NOT have additional properties

This error confuses Claude because:

  • actions is "required" but exists inside output
  • Schema has additionalProperties: false, so output is invalid

Claude tried to "debug" by reducing output from 47 items to 1 item.

Environment

  • claude-agent-sdk==0.1.19
  • Python 3.11+

Related

Activity

  1. AgentWrapper commented on Jan 21, 2026

    @AgentWrapper
    Author

    Additional data point: The wrapper key can also be "response" instead of "output":

    {
      "response": {
        "actions": [...]
      }
    }

    Same error: Output does not match required schema: root: must have required property 'actions', root: must NOT have additional properties

  2. AgentWrapper commented on Jan 21, 2026

    @AgentWrapper
    Author

    Another wrapper variant observed: {"json": {...}} in addition to {"output": {...}} and {"response": {...}}.

  3. Liberot2 commented on Jan 27, 2026

    @Liberot2

    the same question

  4. yarjor commented on Jan 28, 2026

    @yarjor

    +1

  5. developer239 commented on Feb 1, 2026

    @developer239

    +1

  6. InsanePrototyper commented on Feb 2, 2026

    @InsanePrototyper

    Yes, I am also facing this

  7. jmehnle commented on Feb 3, 2026

    @jmehnle

    This is so frustrating. We're now setting ourselves up for just asking for a natural language response from Claude and then using ChatGPT to coerce it into a proper structured response. This appears to be a much more robust strategy.

  8. sihil commented on Mar 31, 2026

    @sihil

    FWIW, the pre tool use hook strategy documented on #374 seems like a good approach as you can rewrite the JSON in that hook and unwrap (or correct as required) before running the structured output tool.

  9. yarjor commented on Apr 1, 2026

    @yarjor

    FWIW, the pre tool use hook strategy documented on #374 seems like a good approach as you can rewrite the JSON in that hook and unwrap (or correct as required) before running the structured output tool.

    This is the solution we currently use, but it is still a bit flaky because once in a while we meet a new keyword we haven't accounted for (e.g we handle "output" and "result" but suddenly get "json")

  10. lionelgwk commented on Apr 15, 2026

    @lionelgwk

    FWIW, the pre tool use hook strategy documented on #374 seems like a good approach as you can rewrite the JSON in that hook and unwrap (or correct as required) before running the structured output tool.

    +1, but so far has anyone else found another workaround worth exploring? Although I would think that the pre tool use hook is fairly decent at mitigating an issue like this.

    The flakiness also seems to be showing when outputs get lengthier.

  11. urielcos commented on May 13, 2026

    @urielcos

    Any updates on progress in this regard? seems like such a basic concept that without it we can't really trust the library.

  12. jmehnle commented on May 27, 2026

    @jmehnle

    I've been battling the unreliability of ClaudeAgentOptions(output_format=...) for months (to the extent that we're now asking Claude Code for informal JSON responses and then give them to OpenAI ChatGPT to reliably produce structured output). Now I just had a confusing conversation with Claude in which it explained that the client.messages.parse(output_format=...) argument (same as output_config.format) guarantees schema-constrained sampling but ClaudeAgentOptions(output_format=...) employs a validate-retry loop, suggesting that it does not use schema-constrained sampling. And of course the entire existence of this issue (#502) indicates that schema-constrained sampling is not used. Can someone from Anthropic enlighten us whether schema-constrained sampling is indeed not used, and, if so, why not?

    (I wish I could share the conversation, but it's in a corporate claude.ai account and can't be shared publicly due to Claude's limitations.)

  13. in-op commented on Jun 5, 2026

    @in-op

    Unbelievable this hasn't been fixed. OpenAI's structured output has worked since day 1

  14. xhbuming commented on Jul 31, 2026

    @xhbuming

    +1

  15. dani-mezei commented on Aug 14, 2026

    @dani-mezei

    +1

  16. in-op commented on Aug 19, 2026

    @in-op

    @qing-ant can you please get this addressed? This is a major blocker to using the agent SDK in any real production system. This should have been the number 1 priority bugfix the day it was created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions