bug: file:// links with spaces in path render as plain unstyled text
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 peris_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.
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
#14641 describes the same symptom but has no root cause analysis. This issue identifies exactly where and why it breaks:
codex-rs/tui/src/markdown_render.rs:759Url::parserejects literal spaces → returnsNone→ both rendering branches inpop_linkare skipped → plain text[text](<file:///path/to/my file.md>), which models use for paths containing spacesUrl::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.Repro
file://literal-space rendering problem on currentmain.file://targets with literal spaces were rendering as plain text instead of staying on the styled local-link path.Root Cause
Url::parserejects literal spaces.file://parsing and updated both duplicated markdown renderers together.Validation
cargo fmt --allcargo test -p codex-tui file_link_with_literal_spaces_uses_target_pathcargo test -p codex-tui-app-server file_link_with_literal_spaces_uses_target_pathRisk
file://parsing and duplicated surfaces were updated together.Maintainer Pickup