Windows desktop app renders external Markdown images as placeholders

Open 💬 2 comments Opened May 21, 2026 by grandmaster451

Codex Desktop Windows: external Markdown images render as placeholders

Environment

  • App: OpenAI.Codex
  • Version: 26.519.2081.0
  • Package: OpenAI.Codex_26.519.2081.0_x64__2p2nqsd0c76g0
  • OS: Windows x64
  • Shell: PowerShell

Summary

In Codex Desktop on Windows, Markdown image links to external HTTPS images rendered as broken image placeholders in the chat UI. This happened even when most image URLs were reachable and returned valid image content from PowerShell.

Steps to reproduce

  1. In Codex Desktop on Windows, send an assistant response with Markdown image syntax using external HTTPS image URLs, for example:

![Ralph Fiennes](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Ralph_Fiennes_from_%22The_White_Crow%22_at_Opening_Ceremony_of_the_Tokyo_International_Film_Festival_2018_%2831747095048%29_%28cropped%29.jpg/500px-Ralph_Fiennes_from_%22The_White_Crow%22_at_Opening_Ceremony_of_the_Tokyo_International_Film_Festival_2018_%2831747095048%29_%28cropped%29.jpg)

  1. Observe the chat UI.
  2. Validate the URLs from PowerShell with Invoke-WebRequest -Method Head or curl.exe -L.

Expected behavior

Images whose URLs return HTTP 200 and an image content type should render inline in the chat UI.

Actual behavior

The UI displayed image placeholders instead of the images.

Troubleshooting performed

  • Three tested image URLs returned HTTP 200 with image/jpeg.
  • One source URL from Britannica returned HTTP 403, so that specific source was legitimately blocked.
  • One GQ image returned HTTP 200 but stalled during a full sequential download; downloading it in byte ranges worked.
  • Local copies of all images were saved and verified as valid JPEG files with normal dimensions.
  • Because every external image showed as a placeholder, including URLs that returned valid image responses, this looks like a Codex Desktop Windows image-rendering/fetching issue rather than only bad image URLs.

Workaround

Download images into the workspace and provide a local HTML preview/gallery. This avoids depending on external image rendering inside the Codex chat UI.

Related issue

Possibly adjacent: https://github.com/openai/codex/issues/14576

View original on GitHub ↗

2 Comments

Harry813 · 1 month ago

This also reproduces on current Codex Desktop for macOS, so it does not appear to be Windows-only.

Environment

  • Codex Desktop: 26.707.31428 (build 5059)
  • Session CLI: 0.144.0-alpha.4
  • macOS, Darwin arm64

Reproduction

An assistant response contained external Markdown images such as:

![Game icon](https://pp.myapp.com/ma_icon/0/icon_12127266_1782349399/256)

The image did not render inline in the Codex conversation.

Validation

At the same time, the URL returned a valid image response:

HTTP/2 200
content-type: image/png
content-length: 136714

The downloaded file was verified as a valid 256x256 RGBA PNG. A second URL on the same CDN also returned HTTP 200 and a valid 256x256 PNG. Requests with Origin: app://codex received a matching access-control-allow-origin: app://codex, so this does not look like an obvious dead URL or CORS rejection.

The assistant had downloaded and validated local copies during the turn, but its final message contained only the external Markdown URLs; the remote bytes were not embedded as message attachments. No specific remote-image error was recorded in the desktop log at render time.

Expected behavior

External HTTPS Markdown images that return HTTP 200 with an image content type should render inline. If the renderer intentionally blocks or cannot fetch a remote image, it should expose a visible failure reason instead of only leaving a broken placeholder.

Current workaround: download the image to a stable local path and render/attach the local copy.

jarvanstack · 1 month ago

I reproduced this on macOS and traced the failure through the packaged desktop renderer and sanitized desktop logs. This adds a more specific reproduction condition and root-cause signal to the earlier macOS report.

Environment

  • Codex Desktop: 26.707.31428 (build 5059)
  • Bundled CLI: 0.144.0-alpha.4
  • macOS arm64
  • Codex authentication mode: API key (not ChatGPT OAuth)

Reproduction URL validation

The external Markdown image returned a valid response outside the renderer:

HTTP 200
Content-Type: image/png
Content-Length: 67587

Renderer path

The packaged renderer handles an HTTP(S) Markdown image by calling:

POST /ecosystem/url_safe

Only when that response reports safe: true does the component use the remote URL as the image source. Otherwise it renders the Image unavailable placeholder.

For this API-key-authenticated Codex session, the desktop main process attempted the request with authentication enabled, but no ChatGPT access token was available:

desktop_fetch_auth_401
hadToken=false
skipRetryReason=no_token_attached
tokenSource=cached
willRetry=false

sa_server_request_failed
attachAuth=true
routePattern=/ecosystem/url_safe
status=401
errorMessage="Unauthorized - Access token is missing"

This occurred once for each external Markdown image. It explains why valid images from unrelated HTTPS hosts all become placeholders and why CORS/CDN checks do not identify the failure.

Likely product gap

Codex can be fully usable with API key authentication, but the Markdown remote-media safety path currently depends on a ChatGPT access token. The desktop auth cache correctly contains no ChatGPT token in API key mode, so /ecosystem/url_safe cannot authorize and the renderer has no alternate path.

Suggested fix

  • Provide a remote-image safety path that works for API-key-authenticated Codex sessions, or route this check through a desktop/App Server capability that does not require ChatGPT OAuth.
  • Do not silently reduce an authentication failure to the generic broken-image placeholder. Show an actionable state if remote media cannot be checked under the current authentication mode.
  • Preserve the existing fail-closed behavior rather than loading arbitrary remote media after a safety-check error.

Suggested regression coverage

  1. Start a local Codex Desktop session authenticated with an API key.
  2. Render user and assistant Markdown containing a valid external HTTPS image.
  3. Verify the safety check has a supported authentication path and the image renders.
  4. Verify an actual unsafe result still renders the blocked placeholder.
  5. Verify a safety-service authentication failure is distinguishable from an unsafe URL and from an image network error.

The affected Markdown renderer and desktop fetch/auth bridge are in the packaged desktop frontend rather than the public Rust repository, so this likely needs an internal desktop change rather than an app-server-only patch.