Codex Desktop: image thumbnails fail with "File stream access denied" — estuary download URL is fetched without Authorization

Open 💬 0 comments Opened Jul 22, 2026 by th3nolo

Summary

Image attachments in Codex Desktop (Windows) render as red "Failed" tiles. The renderer log shows:

warning [electron-message-handler] Image asset download failed
  assetPointer=sediment://file_...
  errorMessage="{\"detail\":\"File stream access denied.\"}"
  pointerScheme=sediment resolverKind=codex

Root cause: the desktop fetches the estuary download URL without any credentials, and /backend-api/estuary/content requires auth. Verified by replaying the exact requests:

| Request | Result |
|---|---|
| GET /backend-api/files/download/{file_id} (with Bearer token) | 200 → returns signed download_url |
| GET https://chatgpt.com/backend-api/estuary/content?id=...&sig=... anonymous | 403 {"detail":"File stream access denied."} |
| Same estuary URL with Bearer + ChatGPT-Account-Id | 200, valid image bytes |

The signed sig query param is not sufficient on its own — the endpoint still demands the Bearer token.

Why the app sends no credentials

In the packaged main bundle (build 26.715.72359):

  1. performDesktopFetch attaches auth only when the request carries the X-OpenAI-Attach-Auth marker header, or when shouldInferCodexApiAuth(url) returns true.
  2. shouldInferCodexApiAuth whitelists only /wham, /api/wham, /backend-api/wham — estuary paths are missing.
  3. The image resolver (prompt-editor chunk) fetches the download_url with requestHeaders = null, so only the infer path could ever attach auth — and it doesn't cover estuary.

The upload path does special-case estuary URLs (unwrapping combined upload URLs); the download path was missed, presumably during the estuary storage migration.

Suggested fix (verified locally)

Add estuary to the infer list:

|| n === `/backend-api/estuary` || n.startsWith(`/backend-api/estuary/`)

in shouldInferCodexApiAuth. I applied this one-line change to a local copy of the packaged app.asar and all previously failing thumbnails (4 sediment://file_... assets across multiple conversations) now download and render correctly.

Environment

  • Codex Desktop app version 26.715.72359 (MSIX package 26.715.10079.0)
  • Windows 11, ChatGPT Pro account
  • Repro: send any image in the composer, then reopen the conversation (or focus it after the local copy is gone) — the thumbnail request goes through the estuary resolver and fails.

Possibly related

  • #29880 (macOS, thumbnails as gray placeholders) — likely the same estuary auth gap
  • #32677 / #33034 (plugin icons/thumbnails broken) — same asset-download code path

View original on GitHub ↗