[BUG] Desktop (Epitaxy) copy-link on a model-authored file link yields a dead https://claude.ai/epitaxy/local_<uuid> URL instead of the file path

Open 💬 4 comments Opened Jun 11, 2026 by leifclaesson

Environment

  • Claude Code Desktop (Epitaxy UI) 2.1.170, Windows 11
  • Model: claude-fable-5 (not at fault -- the model emitted the correct path; see below)

Summary

When Claude renders a markdown link to a local file in its prose reply, right-click -> copy link address yields a dead URL in the app's own namespace instead of the file path the model wrote:

https://claude.ai/epitaxy/local_0f2a7655-d95f-42de-9dc0-f235721acf0c

The local_<uuid> is an internal navigation handle. It is meaningless outside the app, so any "copy the link to open the file elsewhere / paste it into notes" workflow produces a dead link that looks shareable only because it wears a https://claude.ai address.

Cleanest repro: two links to the same file, on the same screen

In one turn, Claude both (a) created a file via a tool call and (b) linked it in the prose summary. The result has two links pointing at the same file with the same real absolute path:

  • The tool-call disclosure link ("created a file" -> expand): copies as the real path C:\misc\apps\GabbaExperience\README-TH-EN.md, opens correctly.
  • The prose summary link: copies as https://claude.ai/epitaxy/local_0f2a7655-..., dead.

Same file, same path, same screen -- one works, one doesn't. So the path itself is not the variable; the source of the link is. The app generates the disclosure link from the tool's structured file_path and preserves it. The prose link comes from the model's markdown, and the renderer wraps it in a local_<uuid> handle that the copy-link handler then surfaces verbatim instead of resolving back to the original href.

The model emitted the correct path (ruling out hallucination)

I first assumed the model was hallucinating the URL, so I checked the session transcript (.claude\projects\...\<sessionId>.jsonl). The model emitted a clean absolute path; the local_<uuid> rewrite happens entirely in the renderer, downstream of the transcript. Verbatim assistant line:

{"parentUuid":"2033b543-c089-4ff3-b77a-cd221e644a9c","isSidechain":false,"message":{"model":"claude-fable-5","id":"msg_01S8tH3g4WhqawUjoM5HQYwC","type":"message","role":"assistant","content":[{"type":"text","text":"Done — the full English translation is at [README-TH-EN.md](C:\\misc\\apps\\GabbaExperience\\README-TH-EN.md), next to the Thai original. It mirrors the Thai edition section for section: the same callout blocks, the table of folder contents, the Mermaid timeline, and all the jokes carried over (the bending needle, the Blaupunkt blue-dot pun, the VOLL'ZIEHEN accident, the hardcoded 11, and the palette-trick-as-mouse-sensor bit).\n\nOne thing I noticed in the Thai source while translating: the word \"floppy\" is written as `ฟลॉปปี้` in three places (lines 16, 72, 202) — that `ॉ` is a stray Devanagari vowel sign, not the Thai `อ` (should be `ฟลอปปี้`). It renders almost identically so it's easy to miss, but it's a typo in [README-TH.md](C:\\misc\\apps\\GabbaExperience\\README-TH.md) if you want to fix it."}],"stop_reason":"end_turn","stop_sequence":null,"stop_details":null,"usage":{"input_tokens":2,"cache_creation_input_tokens":6074,"cache_read_input_tokens":60810,"output_tokens":553,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":6074,"ephemeral_5m_input_tokens":0},"inference_geo":"not_available","iterations":[{"input_tokens":2,"output_tokens":553,"cache_read_input_tokens":60810,"cache_creation_input_tokens":6074,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":6074},"type":"message"}],"speed":"standard"},"diagnostics":null},"requestId":"req_011CbvvuVJf67v2wFp7pQ9BX","type":"assistant","uuid":"d0ab35e8-f6ee-482a-b868-6b60b1521a31","timestamp":"2026-06-11T05:36:08.750Z","userType":"external","entrypoint":"claude-desktop","cwd":"C:\\projects","sessionId":"5be2fc27-917a-4405-a01e-194de6804908","version":"2.1.170","gitBranch":"master"}

Emitted href: C:\misc\apps\GabbaExperience\README-TH-EN.md. Rendered label is the bare filename (by design); the broken local_<uuid> only appears on copy.

Expected

Copy link address on a file link should yield the path the model wrote (the same value the tool-call disclosure link already returns for that file). If the app needs an internal local_<uuid> handle for in-app click navigation, keep it internal -- resolve it back to the real path on copy, and never expose it dressed as a https://claude.ai URL that cannot resolve for anyone.

Fix points at

The markdown link renderer's copy handler -- it copies the internal navigation href instead of the underlying file path. The tool-call disclosure component already does the right thing and can serve as the reference behavior.

View original on GitHub ↗

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