Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

fix: bound $ref expansion in strict JSON schema conversion - #3838

#3838
Merged
seratch merged 1 commit into
openai:mainopenai/openai-agents-python:mainfrom
ioleksiuk:fix/strict-schema-ref-expansion-dosioleksiuk/openai-agents-python:fix/strict-schema-ref-expansion-dosCopy head branch name to clipboard
Jul 15, 2026
Merged

fix: bound $ref expansion in strict JSON schema conversion#3838
seratch merged 1 commit into
openai:mainopenai/openai-agents-python:mainfrom
ioleksiuk:fix/strict-schema-ref-expansion-dosioleksiuk/openai-agents-python:fix/strict-schema-ref-expansion-dosCopy head branch name to clipboard

Conversation

@ioleksiuk

Copy link
Copy Markdown
Contributor

Summary

ensure_strict_json_schema (used for function-tool, output, and MCP tool schemas when convert_schemas_to_strict is enabled) inlines every $ref that has sibling keys and then re-recurses into the inlined subtree, with no cycle detection or expansion limit. A schema whose $defs reference the next level twice therefore expands to 2**N nodes:

  • ~21 levels expand a few-KB schema to hundreds of MB and pin a CPU core for seconds-to-minutes.
  • Because the conversion runs synchronously inside the async run loop, an untrusted schema (for example, a tool schema advertised by a third-party MCP server) can stall the event loop — an algorithmic-complexity denial of service (CWE-400 / CWE-674).

This threads a shared node-visit budget through the recursion. Once the budget is exhausted, conversion raises a UserError instead of expanding unbounded, turning the pathological case into a fast, bounded error. Normal schemas are orders of magnitude below the limit and are unaffected.

Test plan

  • Added test_ref_expansion_bomb_is_rejected: a 30-level $ref fan-out (which would inline to 2**30 nodes) now raises UserError in milliseconds instead of exhausting CPU/memory.
  • Existing strict-schema tests (legitimate $ref inlining, chained refs, unions, etc.) are unchanged and pass.
  • make format, make lint, make typecheck, and make tests pass locally.

Issue number

N/A

Checks

  • I've added new tests, if relevant
  • I've run .agents/skills/code-change-verification/scripts/run.sh
  • I've confirmed all verification steps pass

`_ensure_strict_json_schema` inlines each `$ref` that has sibling keys and
re-recurses into the inlined subtree with no cycle detection or expansion
limit. A schema whose `$defs` reference the next level twice therefore
expands to 2**N nodes: a few-KB schema balloons to hundreds of MB and pins a
CPU core. Because the conversion runs synchronously inside the async run loop,
an untrusted schema (for example, a tool schema advertised by a third-party
MCP server) can stall the event loop (CWE-400 / CWE-674).

Thread a shared node-visit budget through the recursion and raise a UserError
once it is exhausted. This turns the pathological case into a fast, bounded
error while leaving normal schemas unaffected.
@seratch seratch added this to the 0.18.x milestone Jul 15, 2026
@seratch
seratch merged commit 8ce548e into openai:main Jul 15, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.