Skip to content

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

@aamodbhatt

Description

@aamodbhatt

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    TUIIssues related to the terminal user interface: text input, menus and dialogs, and terminal displaybugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions