Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/web
Steps to reproduce
- In a project, create
docs/ai/plans.mdanddocs/ai/design.md. - In
plans.md, name the other file in inline code, written from the repo root:See `docs/ai/design.md`. - Open
plans.mdin the file preview panel in rendered markdown mode. - Hover the
design.mdchip, or click it.
Expected behavior
The chip points to <project>/docs/ai/design.md.
Actual behavior
The chip points to <project>/docs/ai/docs/ai/design.md. The directory of the open file is put in front of a path that already starts at the repo root. That file does not exist, so the link is dead.
The same inline code in a chat message resolves correctly, because chat resolves from the workspace root.
Impact
Minor bug or occasional failure
Version or commit
main @ 3a9c1a6
Environment
Windows desktop app with the server in WSL2, Ubuntu 24.04. The cause is in shared web code, so I do not think it is specific to WSL.
Cause
FileMarkdownPreview passes the open file's directory as imageBaseDir. ChatMarkdown then gives that directory to resolveInlineCodeFileLinkMeta in apps/web/src/markdown-links.ts as the base for every relative inline code path.
#9140 added that base so links in a file outside the workspace resolve beside the file. For a file inside the workspace, prose usually names files from the repo root, so the same base gives a wrong path.
Proposed rule
- A bare inline code path in a workspace file resolves from the workspace root.
- A path that starts with
./or../resolves from the file's directory, as it does now. - A file outside the workspace keeps the current behaviour.
- Explicit markdown links and images keep the current file-relative behaviour.
The trade-off: a package README that writes src/index.ts to mean its own package would resolve from the repo root. The client cannot tell the two cases apart without a check that the file exists.
I have a small fix with focused tests for this rule. I can open a PR if the direction is right.
Workaround
Use a markdown link relative to the file, such as [design](design.md), or start the inline code path with ../.
Investigated with Claude Code, Opus 5.5.
Activity
juliusmarminge commentedon Oct 6, 2026
Note
Grok responding on behalf of Julius.
Triage
Thanks for the clear repro and the careful write-up of the cause, @genericrohan! This matches what we see on
mainat3a9c1a6df. It's specific to the web file preview; chat already resolves these from the workspace root.What I found
FileMarkdownPreviewsetsimageBaseDirto the open file's directory, andChatMarkdownpasses that directory to both explicit link resolution andresolveInlineCodeFileLinkMetainapps/web/src/markdown-links.ts.`docs/ai/design.md`insidedocs/ai/plans.mdgets joined ontodocs/aiand becomesdocs/ai/docs/ai/design.md. Chat leavesimageBaseDirunset, so the same span resolves from the workspace root.openFileInPanel, so clicking the chip opens the doubled path.Likely fix area
Your proposed rule fits the code well. A few details that may matter if inline-code resolution changes:
imageBaseDiras is, so images and explicit markdown links keep resolving from the file's directory (e.g.resolveMarkdownFileLinkMeta("src/main.ts", "/repo", "/repo/docs")stays/repo/docs/src/main.ts).design.md:12orMakefile:12probably read best as sibling references, so they could keep resolving from the file's directory rather than the workspace root../and../paths, and files outside the workspace (the feat(files): open markdown, HTML, and PDF files outside the workspace #9140 case), would keep today's behavior../src/index.tsas the file-relative spelling.apps/web/src/markdown-links.test.tsis the natural place to cover these cases.A maintainer will decide on the fix direction.
Add captures for pingdotgg#16348