Repository navigation
[Bug]: Codex App feature surfaces (Astra trial prompt, built-in image generation) stop working through the proxy #4213
Description
Client or integration
Codex App
Area
Proxy and routing
Summary
Users report that Codex App capabilities beyond the model call stop working while the app is pointed at the OpenCodex proxy, and start working again the moment the proxy is disabled. Two distinct symptoms were reported for the same setup: the GPT-6 Astra trial prompt never appears, and built-in image generation does not produce an image.
Reported on X by @ShineGoal on 2026-09-09 (https://x.com/shinegoal/status/2097582731643498917): after turning the OpenCodex proxy off and restarting ChatGPT, the app immediately offered the GPT-6 Astra trial; they attribute the missing imagegen result to the proxy as well.
Expected: either those app-level calls reach the upstream they need while the proxy is in front of the app, or the failure names itself so the user knows which call was not proxied and what to do about it. Today the user's conclusion is simply "OpenCodex broke my Codex App", which is what the reports show.
Reproduction
- Point Codex App at the local proxy and use it normally.
- Observe that the account-level trial or rollout prompt for a newly released model does not appear, and that built-in image generation does not return an image.
- Stop the proxy, restore the direct configuration, restart the app.
- Observe the trial prompt appears immediately and image generation works.
Source reading at dev 6d3ad12e3 (2.51.0) gives two candidate causes that need separating with a captured request log:
src/server/index.tsserves an explicit allowlist (loopbackRouteAllowed:/v1/responses,/v1/responses/compact,/v1/alpha/search,/v1/images/generations,/v1/images/edits,/v1/models, and the realtime paths) and answers every other/v1/*path with a JSON 404Unknown endpoint: <method> <path>rather than forwarding it upstream. Any app call to an endpoint outside that list - including account-level feature, rollout, or entitlement checks - terminates at the proxy. The allowlist is deliberately default-deny, so this is a design decision, not an accident; what is missing is a decision about native app surfaces and an error that explains itself.- Image generation is a different shape:
/v1/images/generationsis allowlisted, butsrc/server/images.tsreturns400 invalid_request_errorwith "Built-in image generation needs an OpenAI upstream (ChatGPT login or an OpenAI API-key provider) or a logged-in Google Antigravity (Cloud Code Assist) provider, but none is configured in opencodex" when no capable upstream exists. So the image symptom may be a configuration state rather than the 404 path.
Version
Not stated by the reporter (report dated 2026-09-09, when 2.49.0 was current). Source read at dev 6d3ad12e3.
Operating system
Not stated by the reporter.
Provider and model
codex / gpt-6-astra, plus the built-in image_generation tool
Logs or error output
HTTP 404 not_found
Unknown endpoint: POST /v1/<path not in the loopback allowlist>Screenshots and supporting files
X report: https://x.com/shinegoal/status/2097582731643498917
Redacted configuration
{}Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
Ingwannu commentedon Sep 10, 2026
Keeping the two symptoms separate is important. The allowlist and missing-capable-image-upstream branches exist at dev 6d3ad12, but a hypothetical
/v1/<path>404 is not a captured failing Astra-trial request. The bypass observation does not yet identify which app call or authentication context differs.For the next step, please obtain the exact OCX/App versions and sanitized method + endpoint path + status for each symptom (no tokens, query secrets, request bodies, or account identifiers). For image generation, distinguish the built-in tool from the standalone Images API and report only whether a capable authenticated upstream is available. Keep the default-deny route policy: adding a wildcard account/feature passthrough would widen credential forwarding before we know the required endpoint contract. No local app configuration or daemon was changed.
lidge-jun commentedon Sep 10, 2026
리뷰 · 우선순위 42 / 80
이 이슈는 Codex 앱을 OpenCodex 프록시에 물리면, 모델 호출 밖의 앱 기능(예: GPT-6 Astra 체험 안내, 내장 이미지 생성)이 멈추고, 프록시를 끄면 바로 돌아온다는 보고다. X @ShineGoal 보고와 같다. 사용자는 “OpenCodex가 앱을 깨뜨렸다”고 결론짓기 쉽고, 어떤 호출이 막혔는지 설명이 없다.
현재
devHEAD6101140ff(2.51.0)에서 후보는 둘로 갈라져야 한다. 첫째,src/server/index.ts의loopbackRouteAllowed(약 821행)는/v1/responses,/v1/responses/compact,/v1/alpha/search,/v1/images/generations,/v1/images/edits,/v1/models, realtime 등만 허용하고, 그 밖의/v1/*는 약 1074행 부근에서 JSON 404Unknown endpoint: <method> <path>로 끝낸다. 계정·롤아웃·엔타이틀먼트 같은 앱 전용 호출이 이 목록 밖이면 업스트림으로 안 가고 프록시에서 종료된다. 허용 목록은 기본 거부의 의도적 설계이지 실수가 아니다. 빠진 것은 “네이티브 앱 표면을 프록시할지”에 대한 제품 결정과, 막혔을 때 스스로 설명하는 오류다.둘째, 이미지 생성은 다른 모양이다.
/v1/images/generations는 allowlist에 들어가 있지만,src/server/images.ts는 OpenAI 업스트림(ChatGPT 로그인 또는 OpenAI API 키)이나 로그인된 Google Antigravity 등이 없으면400 invalid_request_error와 “Built-in image generation needs an OpenAI upstream …” 메시지를 돌려준다. 즉 Astra 체험(허용 목록 밖 경로 가능)과 imagegen(허용됐지만 업스트림/설정 조건)을 한 버그로 뭉개면 안 된다. 캡처된 요청 로그로 어느 경로가 404인지, 어느 응답이 400인지를 나눠야 한다.feasibility는 #4213을 이번 라운드에서 PARKED(native-surface proxy 설계)로 두었다. 레인에서 지금 구현하지 말고, 디자인 이슈로 열어 두라는 뜻이다. allowlist를 함부로 넓히면 보안·범위가 커지고, types/config 쪼개기와는 별개인 서버 라우팅 설계 문제다.
라인 ~821 -
src/server/index.tsloopbackRouteAllowed: 의도적 allowlist (default-deny)라인 ~1074+ -
src/server/index.ts: allowlist 밖은Unknown endpoint404경로/심볼 -
src/server/images.ts: generations는 allowlist에 있으나 업스트림 없으면 400경로/심볼 - Astra/롤아웃 호출: allowlist 밖일 가능성 → 404로 종료 (확인 로그 필요)
메인테이너의 판단이 필요한 지점
너의 추천
이번 레인에서 구현하지 말고 PARKED로 유지하라. Astra(허용 목록/네이티브 표면)와 imagegen(설정·업스트림)을 이슈 본문에서 섹션으로 분리해 두고, 재현 시 요청 로그로 404 vs 400을 증명하라. 열어 두되 디자인 결정 전에는 allowlist를 넓히지 마라. close-don't-rebase 대상이 아니라 “설계 대기”다.
이 댓글은 grok-bot이 작성했습니다
fix(images): allow managed pool candidates to serve image generation …
lidge-jun commentedon Sep 27, 2026
Release-train 4 investigation. The two symptoms have different causes, so here they are separately. Client references are to
openai/codexat18344a972.Built-in image generation
Codex advertises
image_genonly when theimage_generationfeature is on (the default), the account is not on the Free plan, the provider supports image generation and namespace tools, the selected model accepts image input, and the session uses ChatGPT/Codex backend auth (tool gate). A custom provider is not excluded by name. Once the tool is available, the client POSTs to<provider base_url>/images/generationsor/images/editswithgpt-image-2(backend), so through OpenCodex it reaches/v1/images/generations, which the proxy admits.On the proxy side we found and fixed one concrete failure: when the client authenticated to OpenCodex with a proxy admission token, the Images handler skipped managed Pool accounts entirely and returned the "needs an OpenAI upstream" 400, even though Pool supplies its own stored credential. PR #6097 fixes that (carrying #5927 by @rrmlima), keeps Direct from forwarding the proxy token, and keeps a failed Pool account from falling back to a separately billed API-key provider. Without a capable upstream the handler still returns that 400 on purpose.
So there are two different image outcomes to tell apart: the tool never appears (a client-side gate above: plan, feature flag, auth mode or model input modalities), or the tool call fails (the proxy's Images status).
Astra trial prompt
This is not a blocked proxy route. The public client reads account usage and upsell data from
chatgpt_base_url(defaulthttps://chatgpt.com/backend-api/, e.g.GET /wham/usage,/wham/accounts/check), never from the model provider's/v1base (usage). Model availability prompts come from the model list: the client shows one only when a model row carriesavailability_nux(prompt gate).Behind OpenCodex, Codex reads its model list from the catalog OpenCodex writes (
model_catalog_json) or from its/v1/models. OpenCodex does fetch each account's live ChatGPT roster, butparseAccountModelsinsrc/codex/model-entitlements.tskeeps only eligibility and access metadata and drops the live row'savailability_nux, and the native Astra row is built from a pinned snapshot where that field isnull. A per-account "try Astra" prompt delivered through the model list therefore cannot reach the app while the proxy owns the catalog, and it comes back as soon as the app talks to ChatGPT directly. That matches the report. One caveat: the public Rust client shows that field drives availability prompts, but we cannot see the Desktop app's trial UI source, so this is the strongest candidate rather than a confirmed trace.Plan
Carry a validated
availability_nuxfrom the live roster of the account the app is logged in as onto that account's native row only. Never put it on routed, alias or Reserve rows (those strip it on purpose so one model's prompt is never replayed on another), never let one Pool account's trial show up for another, and clear it when the live roster stops sending it. It needs account-scoped fixtures for both the injected catalog and/v1/models, so it will be a separate PR linked here.If you still see either symptom on a current build, the most useful data is, separately for each symptom: OpenCodex and Codex App versions, whether
image_genappears in the tool list at all, and the sanitized method, path and status of the failing request, plus whether Images used proxy admission auth or a direct ChatGPT bearer (category only). Please leave out request bodies, tokens, credential headers and account identifiers.fix(catalog): carry the main account's model availability prompt onto…
fix(catalog): carry the main account's model availability prompt onto…
fix(catalog): carry the main account's model availability prompt onto…
fix(catalog): carry the main account's model availability prompt onto…
lidge-jun commentedon Sep 27, 2026
Both proxy-side fixes from the analysis above are now on
dev:468b954cc4): a client authenticated to OpenCodex with a proxy admission token can now use managed Pool accounts for built-in image generation instead of getting the "needs an OpenAI upstream" 400.890eb6d660): OpenCodex now carries the logged-in account's live model availability prompt (availability_nux) onto native catalog rows, so a trial or "try this model" prompt delivered through the model list can reach Codex again.Keeping this open until someone confirms on a build that includes both, since the Desktop trial UI isn't public and the prompt only shows for eligible accounts. If it still doesn't appear, the diagnostic list in the previous comment applies.
lidge-jun commentedon Oct 1, 2026
Closing this, because both proxy-side causes found in the investigation have shipped:
468b954cc4) lets a client authenticated with a proxy admission token use managed Pool accounts for built-in image generation, instead of the "needs an OpenAI upstream" 400.890eb6d660) carries the logged-in account'savailability_nuxonto native catalog rows, so a model trial prompt delivered through the model list can reach Codex again.Both are in every stable release since v2.69.0, including the current v2.75.0. Nothing else on the proxy side is left to change here. The remaining cases in the earlier diagnostic list are client-side gates (plan,
image_generationfeature flag, auth mode, model input modalities) or an account that is not eligible for the trial.If the trial prompt or image generation still fails on v2.69.0 or later while it works without the proxy, please open a new issue with the request log rows for the failing call (status and path, no bodies or tokens), and we will pick it up from there.
github-actions commentedon Oct 1, 2026
Automated translation bookkeeping — detected language: English.