TUI renders percent-encoded bare paths instead of decoded Unicode in local file links

Resolved 💬 3 comments Opened Apr 2, 2026 by OnurUenal Closed Apr 6, 2026

Bug

When a model emits Markdown links with bare (non-file://) path destinations containing percent-encoded characters (e.g. %C3%B6 for ö, %20 for spaces), the TUI transcript renderer displays the raw encoded text instead of the decoded file-system path.

Current behavior:

/Volumes/Archiv%201/Bilder/Pers%C3%B6nliches/Kleidung/

Expected behavior:

/Volumes/Archiv 1/Bilder/Persönliches/Kleidung/

Root cause

In codex-rs/tui/src/markdown_render.rs, function parse_local_link_target():

  • The file:// URL code path correctly decodes via Url::to_file_path()
  • But bare paths (starting with /, ~/, ./) are passed through expand_local_link_path() without percent-decoding

Fix

Add urlencoding::decode() before expand_local_link_path() (line ~792):

// Before:
Some((expand_local_link_path(path_text), location_suffix))

// After:
let decoded = urlencoding::decode(path_text).unwrap_or(std::borrow::Cow::Borrowed(path_text));
Some((expand_local_link_path(&decoded), location_suffix))

Also add urlencoding = { workspace = true } to codex-rs/tui/Cargo.toml (already in workspace deps).

Branch with full fix + test: https://github.com/OnurUenal/codex/tree/fix/decode-percent-encoded-bare-paths

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗