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.
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_targetcallsUrl::parseon the raw destination string:Url::parserejects URLs that contain literal spaces and returns anErr. The.ok()?propagates that asNone, sorender_local_link_targetreturnsNone.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:
Models (and editors) generating links to paths with spaces use this syntax. The space reaches
parse_local_link_targetliterally and breaks the URL parser.Reproduction
Fix
Percent-encode spaces before calling
Url::parse. Theurlcrate'sto_file_path()decodes%20back to a space in the output, so the displayed path is correct:I have a branch with the fix + regression test ready if this is a good direction.