Skip to content

fix(streaming): guard against IndexError in Responses API stream accumulator#2942

Open
MaxwellCalkin wants to merge 1 commit intoopenai:mainfrom
MaxwellCalkin:fix/streaming-output-index-bounds-check
Open

fix(streaming): guard against IndexError in Responses API stream accumulator#2942
MaxwellCalkin wants to merge 1 commit intoopenai:mainfrom
MaxwellCalkin:fix/streaming-output-index-bounds-check

Conversation

@MaxwellCalkin
Copy link

Summary

Fixes IndexError: list index out of range that occurs intermittently inside ResponseStreamState.accumulate_event() and handle_event() when output_index references a snapshot output item that has not yet been added.

Fixes #2852

Problem

When streaming Responses API events with tools (e.g., web_search, code_interpreter) or when resuming a stream via starting_after, the stream accumulator can crash with:

File ".../openai/lib/streaming/responses/_responses.py", line 344, in accumulate_event
    IndexError: list index out of range

This happens because several event handlers in both accumulate_event() and handle_event() access snapshot.output[event.output_index] without verifying the index is within bounds. The response.created event initializes the snapshot with an empty (or partially populated) output list, and subsequent events like response.content_part.added, response.output_text.delta, or response.function_call_arguments.delta may reference indices not yet populated by response.output_item.added.

Fix

Adds event.output_index < len(snapshot.output) bounds checks before every snapshot.output[event.output_index] access in both methods:

accumulate_event() — when the index is out of bounds, the snapshot update is silently skipped. The final response.completed event contains the full response data regardless, so no information is lost.

handle_event() — when the index is out of bounds, the raw (un-enriched) event is emitted to the caller instead of crashing. This preserves the event stream and lets consumers handle the event directly.

Affected event types:

  • response.content_part.added
  • response.output_text.delta
  • response.output_text.done
  • response.function_call_arguments.delta

Test plan

  • Verify the fix handles out-of-bounds output indices gracefully
  • Confirm normal streaming (in-order events) is unaffected — the bounds check is a no-op when indices are valid
  • Confirm get_final_response() still returns the complete parsed response

🤖 Generated with Claude Code

…ream accumulator

Fixes IndexError (list index out of range) that occurs intermittently in
ResponseStreamState.accumulate_event() and handle_event() when
output_index references an item not yet added to the snapshot.

This happens when using the Responses API with streaming and tools
(e.g., web_search, code_interpreter) or when resuming streams with
starting_after. The API may deliver events referencing output indices
that have not yet been populated via response.output_item.added.

The fix adds bounds checks before accessing snapshot.output[output_index]
in both accumulate_event() and handle_event(). When the index is out of
bounds, accumulate_event() silently skips the snapshot update (the final
response.completed event will have the full data), and handle_event()
falls back to emitting the raw event without snapshot enrichment.

Fixes openai#2852
@MaxwellCalkin MaxwellCalkin requested a review from a team as a code owner March 8, 2026 12:30
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf39cab8d9

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

Comment on lines +296 to +297
else:
events.append(event)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve parsed done events when output index is missing

When response.output_text.done arrives with an out-of-bounds output_index, this branch now emits the raw event object, which does not have the parsed field that responses.stream() consumers expect for response.output_text.done events. In the exact tool/resume scenarios this patch targets, user code that accesses event.parsed after checking event.type == "response.output_text.done" will still fail (now with AttributeError instead of IndexError), even though parsing can still be performed from event.text without needing snapshot state.

Useful? React with 👍 / 👎.

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.

IndexError in accumulate_event during Responses API streaming

1 participant