Skip to content

[openai-responses] Strip unsupported prompt_cache_options parameter on canonical ChatGPT Codex forward #2765

Description

@Liang-Psych

Client or integration

VS Code / GitHub Copilot (via /v1/responses BYOK endpoint)

Provider or upstream service

ChatGPT Codex forward / openai-responses

OpenCodex version

2.34.0

Endpoint or capability

/v1/responses, OpenAI Responses adapter

Current behaviour

Following the fixes in #2668 and #2648, VS Code / GitHub Copilot requests to gpt-5.6-luna (and other native forward models) now still fail when the client includes top-level "prompt_cache_options" (e.g. {"prompt_cache_options": { ... }}) in the /v1/responses request.

OpenCodex forwards this payload directly to the ChatGPT Codex backend, which rejects it with HTTP 502:

{
  "status": 502,
  "errorCode": "upstream_server_error",
  "upstreamError": "Unsupported parameter: prompt_cache_options"
}

As a result, VS Code Copilot fails on turn start with generic code: 0 / "The model provider reported a failed response without any error details".

Expected behaviour

The openai-responses forward adapter should automatically strip the unsupported prompt_cache_options parameter when dispatching to the canonical ChatGPT Codex forward backend (isCanonicalOpenAiForwardProvider / authMode === "forward"), similar to how truncation is stripped in #2668 / #2672.

Additionally, src/responses/schema.ts (responsesRequestSchema) should accept prompt_cache_options: z.unknown().optional() so valid Responses API requests containing prompt cache options pass schema validation.

Minimal redacted request or reproduction

  1. Send a request to POST http://127.0.0.1:7861/v1/responses:
{
  "model": "gpt-5.6-luna",
  "store": false,
  "stream": true,
  "truncation": "disabled",
  "prompt_cache_options": {
    "ttl": 3600
  },
  "input": [
    {
      "type": "message",
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "hi"
        }
      ]
    }
  ]
}
  1. Request fails with HTTP 502 (Unsupported parameter: prompt_cache_options).

Actual response or error

{
  "status": 502,
  "errorCode": "upstream_server_error",
  "upstreamError": "Unsupported parameter: prompt_cache_options"
}

Upstream documentation

https://platform.openai.com/docs/api-reference/responses

Suggested mapping or implementation notes

  1. In src/responses/schema.ts:
    Add prompt_cache_options: z.unknown().optional() to responsesRequestSchema.

  2. In src/adapters/openai-responses.ts:
    Strip prompt_cache_options in normalizeCanonicalForwardPromptEnvelope or stripUnsupportedForwardParams when dispatching to the canonical ChatGPT Codex forward destination.

Checks

  • I searched existing provider and compatibility issues.
  • The request and response were redacted.
  • The expected behaviour is based on an upstream specification or a concrete client requirement.

Activity

  1. Ingwannu commented on Aug 27, 2026

    @Ingwannu
    Owner

    I confirmed the current dev@8b1b65b8d path that makes this report possible. parseRequest() deliberately retains the caller's original object in _rawBody, and the canonical forward adapter currently has an explicit regression test requiring caller-sent prompt_cache_options to survive. The reported upstream rejection therefore contradicts a real existing compatibility assumption; it is not a Zod-validation failure.

    I will keep the fix narrower than the suggested implementation:

    • strip prompt_cache_options only for isCanonicalOpenAiForwardProvider(...);
    • preserve it for OpenAI API-key and noncanonical/custom Responses providers;
    • update the existing pass-through regression and the canonical-forward compatibility evidence/documentation;
    • do not add the field to responsesRequestSchema, because passthrough already uses _rawBody and adding it would not affect the wire result.

    I am treating the redacted 502 as valid destination evidence and will open a separate PR with focused negative-path coverage. This issue will remain open until that PR has exact-head CI, non-author review, and merge.

  2. Ingwannu commented on Aug 27, 2026

    @Ingwannu
    Owner

    The bounded implementation is now in draft PR #2767: #2767

    The pre-fix canonical adapter test and versioned production fixture both proved that prompt_cache_options reached the wire. After the destination-scoped strip, focused isolated validation is 114/114 green, including gpt-5.6-luna, another canonical model, and preservation controls for OpenAI API-key plus noncanonical forward providers.

    As noted earlier, no responsesRequestSchema field was added because _rawBody already preserves passthrough input and the schema change would not alter dispatch. The issue remains open and the PR remains Draft until the independent current-dev gate regression in #2766 is repaired, exact-head CI is green, and a non-author maintainer reviews/merges it.

  3. lidge-jun commented on Aug 27, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 77 / 80

    이 이슈는 VS Code / GitHub Copilot이 /v1/responses로 gpt-5.6-luna 같은 네이티브 forward 모델에 요청할 때, 공개 Responses 모양의 prompt_cache_options를 넣으면 ChatGPT Codex 백엔드가 Unsupported parameter: prompt_cache_options로 거절하고 OpenCodex가 HTTP 502(upstream_server_error)로 감싸서 클라이언트가 빈 실패를 보게 되는 버그입니다. 지금 dev HEAD 8b1b65b8d를 보면, #2668/#2672에서 truncation은 normalizeCanonicalForwardPromptEnvelope(약 1202행)에서 canonical forward 경계에서만 빼고 있습니다. 같은 파일의 stripDeprecatedPromptCacheRetention(약 333행)은 prompt_cache_retention만 제거하고, canonical 분기(약 2002–2006행)에는 prompt_cache_options strip이 없습니다. 그래서 이슈 재현 JSON은 현재 코드로도 그대로 502가 납니다.

    한 가지 더 중요한 점입니다. 주석(약 321행)은 GPT-5.6이 레거시 retention을 prompt_cache_options.ttl로 대체했다고 말하지만, 이슈가 보여 주듯이 canonical ChatGPT Codex 백엔드는 그 대체 필드 자체도 거절합니다. 그리고 tests/openai-responses-passthrough.test.ts의 keeps caller-sent prompt_cache_options while dropping the retired retention 테스트는 지금 canonical forward에서 options를 보존하도록 고정해 두었습니다. 즉 코드·테스트·주석이 모두 “options는 살아 남아야 한다” 쪽에 맞춰져 있어서, 이슈는 그 가정이 틀렸다는 증거입니다.

    스키마 쪽 제안도 짚겠습니다. src/responses/schema.ts의 responsesRequestSchema(약 143행)에는 prompt_cache_key와 truncation은 있지만 prompt_cache_options는 없습니다. 다만 parseRequest는 원본 body를 _rawBody에 그대로 넣으므로(parser.ts 약 810행), Zod에 필드를 추가하지 않아도 호출자 값은 이미 패스스루됩니다. 그래서 핵심 수정은 스키마 추가가 아니라, canonical forward destination에서만 필드를 제거하는 쪽입니다. API-key·커스텀 forward까지 전역 strip하면 공개 API 계약을 깨뜨릴 수 있습니다.

    라인 openai-responses.ts stripDeprecatedPromptCacheRetention 주석 L321 - GPT-5.6이 retention을 prompt_cache_options로 대체했다고 적혀 있지만, canonical 백엔드는 options도 거절합니다. 주석이 실제 wire와 어긋납니다.

    라인 openai-responses.ts L2002-2006 - isCanonicalOpenAiForwardProvider 안에서 retention strip과 normalizeCanonicalForwardPromptEnvelope만 호출합니다. prompt_cache_options 제거가 없습니다.

    라인 schema.ts responsesRequestSchema - prompt_cache_options 키가 없습니다. 다만 _rawBody 패스스루 때문에 Zod 추가만으로는 wire가 바뀌지 않습니다. 이슈의 “스키마에 추가”는 문서/검증 편의일 뿐, 실질 fix 지점은 어댑터 destination boundary입니다.

    라인 tests/openai-responses-passthrough.test.ts keeps caller-sent prompt_cache_options - 현재는 canonical에서 options 보존을 기대합니다. 수정 PR은 이 기대를 뒤집고, 커스텀 forward·API-key 보존 네거티브도 같이 고정해야 합니다.

    메인테이너의 판단이 필요한 지점

    • Zod에 prompt_cache_options를 문서용으로 넣을지, _rawBody만으로 충분한지
    • strip 범위를 gpt-5.6 family만으로 좁힐지, canonical forward 전체 모델에 적용할지(이슈·재현은 luna 포함)
    • 초안 PR #2767을 이 이슈의 정식 수정으로 받을지

    너의 추천
    이슈는 유효하고 우선순위가 높습니다. schema.ts 추가는 필수가 아닙니다. #2767처럼 isCanonicalOpenAiForwardProvider 경계에서만 prompt_cache_options를 제거하고, 커스텀/API-key는 보존하는 작은 PR을 받으세요. 기존 “options 보존” 테스트를 깨뜨린 뒤 canonical 제거·비canonical 보존으로 다시 고정하면 됩니다. types.ts/config.ts 분할 캠페인과는 무관합니다.

    이 댓글은 grok-bot이 작성했습니다

  4. lidge-jun commented on Aug 27, 2026

    @lidge-jun
    Owner

    Landed via #2767 at 50e9556

  5. lidge-jun commented on Aug 27, 2026

    @lidge-jun
    Owner

    Already on dev via #2767.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    landed-via-maintainerOriginal PR closed after landing via a maintainer merge trainproviderProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reports

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions