Skip to content

fix: avoid mutating FunctionTool params_json_schema#3382

Open
ioleksiuk wants to merge 1 commit into
openai:mainfrom
ioleksiuk:fix/avoid-mutating-function-tool-params-schema
Open

fix: avoid mutating FunctionTool params_json_schema#3382
ioleksiuk wants to merge 1 commit into
openai:mainfrom
ioleksiuk:fix/avoid-mutating-function-tool-params-schema

Conversation

@ioleksiuk
Copy link
Copy Markdown
Contributor

Summary

Mirror the MCP fix in #3134 for the FunctionTool path. ensure_strict_json_schema is documented as mutating its input dict, but FunctionTool.__post_init__ currently passes self.params_json_schema directly. When users construct FunctionTool(...) with a schema dict they own (e.g. reused across instances), strict-mode side effects like additionalProperties: false and required: [...] get baked into the caller's dict.

The decorator-based function_tool(...) path is unaffected because function_schema() produces a fresh dict per call. The direct FunctionTool(...) constructor is documented and exported from agents.__init__, so callers who use it directly are exposed.

>>> shared = {"type": "object", "properties": {"x": {"type": "string"}}}
>>> ft = FunctionTool(name="t", description="d", params_json_schema=shared,
...                   on_invoke_tool=noop, strict_json_schema=True)
>>> shared
{'type': 'object', 'properties': {'x': {'type': 'string'}},
 'additionalProperties': False, 'required': ['x']}

Wrap the schema in copy.deepcopy() before passing to ensure_strict_json_schema, matching the MCP precedent at `src/agents/mcp/util.py:286`.

Test plan

  • New regression test `test_function_tool_does_not_mutate_params_json_schema` (mirrors `tests/mcp/test_mcp_util.py::test_to_function_tool_does_not_mutate_mcp_input_schema`).
  • `uv run pytest tests/test_function_tool.py tests/mcp/test_mcp_util.py` — 112 passed.
  • `uv run ruff check src/agents/tool.py tests/test_function_tool.py` — All checks passed.

Issue number

N/A — found while auditing for the same mutation-aliasing pattern that #3134 fixed.

Checks

  • I've added new tests (if relevant)
  • I've added/updated the relevant documentation (no doc changes needed)
  • I've run `make lint` and `make format`
  • I've made sure tests pass

Mirror the MCP fix in openai#3134 for the FunctionTool path. `ensure_strict_json_schema`
is documented as mutating its input dict, so passing the caller's
`params_json_schema` directly into it leaks strict-mode side effects
(`additionalProperties: false`, `required: [...]`) back into the user's dict.
Users who construct `FunctionTool(...)` directly with a shared schema dict can
observe the mutation, particularly when reusing the dict across instances.

Wrap the schema in `copy.deepcopy()` before passing to
`ensure_strict_json_schema`, matching the MCP precedent.
@seratch
Copy link
Copy Markdown
Member

seratch commented May 13, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

ℹ️ 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".

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