Skip to content

feat: honor tool_not_found_behavior for missing custom tool calls#3707

Closed
gaurav0107 wants to merge 2 commits into
openai:mainfrom
gaurav0107:feat/325-tool-not-found-return-error-custom-tools
Closed

feat: honor tool_not_found_behavior for missing custom tool calls#3707
gaurav0107 wants to merge 2 commits into
openai:mainfrom
gaurav0107:feat/325-tool-not-found-return-error-custom-tools

Conversation

@gaurav0107

Copy link
Copy Markdown

Summary

When the model emits a custom tool call (custom_tool_call) for a tool the
agent does not have, process_model_response always raised
ModelBehaviorError and aborted the whole run, ignoring
RunConfig.tool_not_found_behavior. The "return_error_to_model" opt-in was
only honored for function tool calls.

This change makes a missing custom tool follow the same recovery path as a
missing function tool: when tool_not_found_behavior="return_error_to_model"
is set, the unresolved custom tool call is surfaced back to the model as a
custom_tool_call_output error (the correct output type for a custom tool
call) and the run continues, instead of crashing. The default
"raise_error" behavior is completely unchanged.

Specifically:

  • Add ToolRunCustomNotFound and a custom_tools_not_found field on
    ProcessedResponse (appended at the end; internal run-loop types).
  • Honor return_error_to_model in the ResponseCustomToolCall not-found
    branch, mirroring the existing function-tool branch.
  • Build a custom_tool_call_output error item for missing custom tools,
    reusing the same shape already produced by the successful and rejected
    custom-tool paths.
  • Pass tool_type="custom" through to ToolErrorFormatterArgs so a custom
    tool_error_formatter sees the correct tool type.
  • Update the tool_not_found_behavior docstring to cover custom tools.

Test plan

  • make format, make lint, make typecheck (mypy + pyright) all pass.
  • make tests passes (full suite).
  • Added two tests in tests/test_process_model_response.py:
    • a missing custom tool still raises ModelBehaviorError by default, and
    • with tool_not_found_behavior="return_error_to_model" it records one
      custom_tools_not_found entry and does not raise.

Issue number

Related to #325 (focused slice: recover from the model calling a
non-existent custom tool, rather than a general retry mechanism).

Checks

  • I've added new tests, if relevant
  • I've run make format, make lint, make typecheck, and make tests
  • I've confirmed all verification steps pass

When the model emitted a custom tool call for a tool the agent does not
have, process_model_response always raised ModelBehaviorError and aborted
the run, ignoring RunConfig.tool_not_found_behavior. Only function tool
calls honored the "return_error_to_model" opt-in.

Surface a missing custom tool back to the model as a custom_tool_call_output
error when return_error_to_model is set, mirroring the existing function-tool
path, so the run can recover instead of crashing. The default raise_error
behavior is unchanged.

Related to openai#325
Add Runner-level tests that drive a missing custom tool call through
return_error_to_model and assert the run recovers and the next turn input
contains a custom_tool_call_output with the missing call id and the
not-found message, including a tool_error_formatter variant that confirms
tool_type is "custom".
@gaurav0107 gaurav0107 marked this pull request as ready for review June 29, 2026 21:09
@seratch

seratch commented Jun 30, 2026

Copy link
Copy Markdown
Member

Thanks for the contribution. The implementation demonstrates that missing custom tool calls could follow the existing function-tool recovery path, but we do not currently have evidence of a concrete user-facing need for this extension.

The reports in #325 and #3459 concern missing function tools, which are already covered by #3461. This PR does not include a real custom-tool reproduction, provider scenario, or user report showing that an unavailable custom tool call occurs in practice. Given the narrow reach and the additional runtime, tracking, testing, and documentation surface, I do not think the maintenance cost is justified yet.

I am going to close this PR for now. We can revisit the design if we receive a concrete custom-tool reproduction, including the provider and how the unavailable tool call was produced.

@seratch seratch closed this Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants