Skip to content

fix(strict-schema): preserve chained $ref during sibling-key expansion#3205

Merged
seratch merged 1 commit intoopenai:mainfrom
adityasingh2400:fix/strict-audit
May 8, 2026
Merged

fix(strict-schema): preserve chained $ref during sibling-key expansion#3205
seratch merged 1 commit intoopenai:mainfrom
adityasingh2400:fix/strict-audit

Conversation

@adityasingh2400
Copy link
Copy Markdown
Contributor

Summary

When a $ref pointing to an alias definition (a $ref-only schema that itself points to another definition) had sibling keys like description, ensure_strict_json_schema silently dropped the inner $ref and lost the underlying type. The merge {**resolved, **json_schema} ran while json_schema still contained its own $ref, so the resolved schema's $ref was overwritten by the original (now-stale) $ref, and the subsequent pop("$ref") then removed it entirely.

This is a small, surgical fix: pop the original $ref from the schema before the merge so the resolved schema's $ref (if any) survives into the recursive expansion call. The recursive call then fully resolves the chain.

Repro (failed before fix)

schema = {
    "$defs": {
        "Inner": {"type": "string"},
        "Outer": {"$ref": "#/$defs/Inner"},
    },
    "type": "object",
    "properties": {"a": {"$ref": "#/$defs/Outer", "description": "desc"}},
}
ensure_strict_json_schema(schema)
# Before: properties.a == {"description": "desc"}    -- type lost
# After:  properties.a == {"description": "desc", "type": "string"}

This pattern arises naturally when Pydantic models reference other models that are themselves thin aliases (e.g. RootModel, generic aliases, type aliases that emit single-key $ref definitions).

Test plan

  • New regression test test_chained_ref_with_sibling_keys_is_resolved in tests/test_strict_schema.py fails before the fix and passes after.
  • All existing tests/test_strict_schema.py and tests/test_strict_schema_oneof.py tests still pass (19 passed).
  • Broader related suites unaffected: tests/test_function_schema.py, tests/test_agent_runner.py, tests/test_function_tool.py, tests/mcp/test_mcp_util.py (305 total passed, 0 failed).

When a $ref pointing to an alias definition (a $ref-only schema that
itself points to another definition) had sibling keys like `description`,
`ensure_strict_json_schema` silently dropped the inner $ref and lost
the actual type. The merge `{**resolved, **json_schema}` ran while
json_schema still contained its own $ref, so the resolved schema's
$ref was overwritten before the subsequent pop removed it entirely.

Pop the original $ref before the merge so the resolved schema's $ref
survives into the recursive expansion call, allowing the chain to
fully resolve.
@github-actions github-actions Bot added bug Something isn't working feature:core labels May 8, 2026
@seratch
Copy link
Copy Markdown
Member

seratch commented May 8, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@seratch seratch added this to the 0.17.x milestone May 8, 2026
@seratch seratch merged commit f32f613 into openai:main May 8, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working feature:core

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants