Skip to content

fix(codex): strip stream_options from Responses API requests#2347

Merged
luispater merged 1 commit intorouter-for-me:devfrom
edlsh:fix/codex-strip-stream-options
Mar 28, 2026
Merged

fix(codex): strip stream_options from Responses API requests#2347
luispater merged 1 commit intorouter-for-me:devfrom
edlsh:fix/codex-strip-stream-options

Conversation

@edlsh
Copy link
Copy Markdown
Contributor

@edlsh edlsh commented Mar 25, 2026

Problem

The Codex/OpenAI Responses API does not support the stream_options parameter. When clients such as Amp CLI include stream_options in their requests, CLIProxyAPI forwards it verbatim to the upstream /responses endpoint, resulting in a 400 error:

{"detail":"Unsupported parameter: stream_options"}

Both OAuth accounts are tried and both fail, so the request is never fulfilled.

Log evidence:

[codex_executor.go:360] request error, error status: 400, error message: {"detail":"Unsupported parameter: stream_options"}

Fix

Strip stream_options from the request body before forwarding to the Codex Responses API, consistent with how previous_response_id, prompt_cache_retention, and safety_identifier are already stripped.

Applied in all three code paths:

  • Execute (non-streaming fetch)
  • ExecuteStream (streaming)
  • CountTokens (token counting)

Testing

  • Confirmed the fix compiles cleanly (go build ./internal/runtime/executor/).
  • The change is a single sjson.DeleteBytes call per method, following the identical pattern used for the adjacent parameter deletions.

The Codex/OpenAI Responses API does not support the stream_options
parameter. When clients (e.g. Amp CLI) include stream_options in their
requests, CLIProxyAPI forwards it as-is, causing a 400 error:

  {"detail":"Unsupported parameter: stream_options"}

Strip stream_options alongside the other unsupported parameters
(previous_response_id, prompt_cache_retention, safety_identifier)
in Execute, ExecuteStream, and CountTokens.
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a critical issue where requests to the Codex/OpenAI Responses API were failing due to the inclusion of an unsupported stream_options parameter. By proactively removing this parameter from all outgoing requests, the change ensures the stability and reliability of interactions with the API, preventing service disruptions for clients.

Highlights

  • Unsupported Parameter Fix: The stream_options parameter is now stripped from requests sent to the Codex/OpenAI Responses API. This resolves 400 errors caused by the API not supporting this parameter.
  • Consistent Parameter Handling: This change aligns with existing logic that already strips other unsupported parameters such as previous_response_id, prompt_cache_retention, and safety_identifier.
  • Comprehensive Application: The fix has been applied across all three relevant code paths within the CodexExecutor: Execute (non-streaming fetch), ExecuteStream (streaming), and CountTokens (token counting).

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request modifies codex_executor.go to consistently delete the stream_options field from the request body in the Execute, ExecuteStream, and CountTokens functions. The review comments highlight that the parameter deletion logic is duplicated across these functions and suggest refactoring it into a loop, potentially using a package-level variable, to improve code maintainability and reduce redundancy.

Comment on lines 113 to +116
body, _ = sjson.DeleteBytes(body, "previous_response_id")
body, _ = sjson.DeleteBytes(body, "prompt_cache_retention")
body, _ = sjson.DeleteBytes(body, "safety_identifier")
body, _ = sjson.DeleteBytes(body, "stream_options")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This block of parameter deletions is duplicated in ExecuteStream and CountTokens. To improve maintainability, consider refactoring this into a loop over a slice of parameter names. For even better maintainability, this slice could be defined as a package-level variable to be shared across all three functions.

Suggested change
body, _ = sjson.DeleteBytes(body, "previous_response_id")
body, _ = sjson.DeleteBytes(body, "prompt_cache_retention")
body, _ = sjson.DeleteBytes(body, "safety_identifier")
body, _ = sjson.DeleteBytes(body, "stream_options")
for _, param := range []string{
"previous_response_id",
"prompt_cache_retention",
"safety_identifier",
"stream_options",
} {
body, _ = sjson.DeleteBytes(body, param)
}

Comment on lines 312 to +315
body, _ = sjson.DeleteBytes(body, "previous_response_id")
body, _ = sjson.DeleteBytes(body, "prompt_cache_retention")
body, _ = sjson.DeleteBytes(body, "safety_identifier")
body, _ = sjson.DeleteBytes(body, "stream_options")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This block of parameter deletions is duplicated from Execute and also present in CountTokens. To improve maintainability, consider refactoring this into a loop over a slice of parameter names. For even better maintainability, this slice could be defined as a package-level variable to be shared across all three functions.

Suggested change
body, _ = sjson.DeleteBytes(body, "previous_response_id")
body, _ = sjson.DeleteBytes(body, "prompt_cache_retention")
body, _ = sjson.DeleteBytes(body, "safety_identifier")
body, _ = sjson.DeleteBytes(body, "stream_options")
for _, param := range []string{
"previous_response_id",
"prompt_cache_retention",
"safety_identifier",
"stream_options",
} {
body, _ = sjson.DeleteBytes(body, param)
}

Comment on lines 417 to +420
body, _ = sjson.DeleteBytes(body, "previous_response_id")
body, _ = sjson.DeleteBytes(body, "prompt_cache_retention")
body, _ = sjson.DeleteBytes(body, "safety_identifier")
body, _ = sjson.DeleteBytes(body, "stream_options")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This block of parameter deletions is duplicated from Execute and ExecuteStream. To improve maintainability, consider refactoring this into a loop over a slice of parameter names. For even better maintainability, this slice could be defined as a package-level variable to be shared across all three functions.

Suggested change
body, _ = sjson.DeleteBytes(body, "previous_response_id")
body, _ = sjson.DeleteBytes(body, "prompt_cache_retention")
body, _ = sjson.DeleteBytes(body, "safety_identifier")
body, _ = sjson.DeleteBytes(body, "stream_options")
for _, param := range []string{
"previous_response_id",
"prompt_cache_retention",
"safety_identifier",
"stream_options",
} {
body, _ = sjson.DeleteBytes(body, param)
}

Copy link
Copy Markdown
Collaborator

@luispater luispater left a comment

Choose a reason for hiding this comment

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

Summary:
This PR fixes a real compatibility issue by stripping stream_options before forwarding requests to the Codex Responses API. The change is minimal, targeted, and consistent with existing payload sanitization logic.

Key findings:

  • Blocking: None.
  • Non-blocking: Please consider adding a regression test that asserts stream_options is removed across non-streaming, streaming, and token-count paths.

Test plan:

  • Reviewed PR metadata, diff, and checks.
  • Verified the change is applied in all three intended request-building paths.

Recommendation:
Approve.

This is an automated Codex review result and still requires manual verification by a human reviewer.

@luispater luispater changed the base branch from main to dev March 28, 2026 13:02
@luispater luispater merged commit b9b127a into router-for-me:dev Mar 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants