bug: file:// links with spaces in path render as plain unstyled text

Open 💬 3 comments Opened Mar 14, 2026 by aamodbhatt
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

file:// links whose path contains a literal space render as plain unstyled text in the TUI transcript instead of showing the resolved file path with cyan styling.

Root cause

In codex-rs/tui/src/markdown_render.rs, parse_local_link_target calls Url::parse on the raw destination string:

if dest_url.starts_with("file://") {
    let url = Url::parse(dest_url).ok()?;   // ← fails silently on spaces

Url::parse rejects URLs that contain literal spaces and returns an Err. The .ok()? propagates that as None, so render_local_link_target returns None.

Back in push_link, this means:

  • show_destination = false (it IS a local path per is_local_path_like_link)
  • local_target_display = None (parse failed)

In pop_link, neither rendering branch fires — the link label text is emitted as-is with no style and no destination shown. The result looks like plain text.

When does this happen?

CommonMark disallows bare spaces in link destinations, but allows them when the destination is wrapped in angle brackets:

[my file](<file:///Users/alex/projects/my project/README.md>)

Models (and editors) generating links to paths with spaces use this syntax. The space reaches parse_local_link_target literally and breaks the URL parser.

Reproduction

let text = render_markdown_text_for_cwd(
    "[my file](<file:///Users/example/code/codex/my file.md>)",
    Path::new("/Users/example/code/codex"),
);
// Currently renders as plain "my file" text instead of styled "my file.md"

Fix

Percent-encode spaces before calling Url::parse. The url crate's to_file_path() decodes %20 back to a space in the output, so the displayed path is correct:

let url = if dest_url.contains(' ') {
    Url::parse(&dest_url.replace(' ', "%20")).ok()?
} else {
    Url::parse(dest_url).ok()?
};

I have a branch with the fix + regression test ready if this is a good direction.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 5 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #14641

Powered by Codex Action

aamodbhatt · 5 months ago

#14641 describes the same symptom but has no root cause analysis. This issue identifies exactly where and why it breaks:

  • File: codex-rs/tui/src/markdown_render.rs:759
  • Cause: Url::parse rejects literal spaces → returns None → both rendering branches in pop_link are skipped → plain text
  • Trigger: valid CommonMark angle-bracket syntax [text](<file:///path/to/my file.md>), which models use for paths containing spaces
  • Fix: percent-encode spaces before Url::parse (shown in the issue body)

A branch with the fix + regression test is at aamodbhatt/codex@fix/file-url-spaces-in-markdown-links. Happy to open a PR if that's useful.

middleDuckAi · 5 months ago

Repro

  • Reproduced the file:// literal-space rendering problem on current main.
  • file:// targets with literal spaces were rendering as plain text instead of staying on the styled local-link path.

Root Cause

  • The raw target was degrading to plain text because Url::parse rejects literal spaces.
  • I prepared a narrow renderer fix that only applies to file:// parsing and updated both duplicated markdown renderers together.

Validation

  • cargo fmt --all
  • cargo test -p codex-tui file_link_with_literal_spaces_uses_target_path
  • cargo test -p codex-tui-app-server file_link_with_literal_spaces_uses_target_path

Risk

  • Low. The fallback is limited to file:// parsing and duplicated surfaces were updated together.

Maintainer Pickup

gh pr create --repo openai/codex --base main --head middleDuckAi:middleDuck/codex-14688-file-links-with-spaces --title "$(gh pr view 4 --repo middleDuckAi/codex --json title --jq .title)" --body "$(gh pr view 4 --repo middleDuckAi/codex --json body --jq .body)"