Skip to content

_sanitize_openai_conversation_item strips required id from built-in tool-call items #2865

@ryantn-renn

Description

@ryantn-renn

Bug

_sanitize_openai_conversation_item() in agents/run_internal/session_persistence.py:568 unconditionally strips id from all conversation items before calling session.add_items():

def _sanitize_openai_conversation_item(item):
    if isinstance(item, dict):
        clean_item = cast(dict[str, Any], strip_internal_input_item_metadata(item))
        clean_item.pop("id", None)       # strips id from ALL items
        clean_item.pop("provider_data", None)
        return cast(TResponseInputItem, clean_item)
    return item

The OpenAI Conversations API requires id on built-in tool-call item types. The SDK's own response param type definitions confirm this:

  • ResponseFileSearchToolCallParamid: Required[str] (openai/types/responses/response_file_search_tool_call_param.py:43)
  • ResponseCodeInterpreterToolCallParamid: Required[str] (openai/types/responses/response_code_interpreter_tool_call_param.py:37)
  • ResponseFunctionWebSearchParamid: Required[str] (openai/types/responses/response_function_web_search_param.py:79)

When the sanitizer strips id from these items, the Conversations API returns 400 Missing required parameter: 'items[0].id'.

Reproduction

  1. Create an agent with FileSearchTool and a real vector store
  2. Use OpenAIConversationsSession for conversation persistence
  3. On turn 1, trigger the agent to use file_search (produces file_search_call items)
  4. On turn 2, send any follow-up message
  5. The SDK collects turn 1's output items, sanitizes them (stripping id), and calls add_items()
  6. The Conversations API rejects the batch because file_search_call is missing id

Failing batch shape

[
  {"type": "file_search_call", ...},       // id: Required — stripped by sanitizer → 400 error
  {"type": "function_call", ...},          // id: Optional — works without id
  {"type": "function_call_output", ...}    // id: Optional — works without id
]

Note: function_call has id as optional in the SDK type definitions (response_function_tool_call_param.py:29). The confirmed required-id types are file_search_call, code_interpreter_call, and web_search_call.

Workaround

Override the sanitizer to only strip id from item types where it's optional (role == "user", type == "function_call_output"), preserving it for everything else.

Environment

  • openai-agents==0.13.5
  • openai==2.30.0
  • Python 3.13.6
  • Agent uses: FileSearchTool, CodeInterpreterTool, custom @function_tool tools
  • Session: OpenAIConversationsSession (subclassed for batching)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions