[Bug]: Relative file links with non-ASCII paths don't open#16096

opened20d agobySstickerdaniel

I was studying for a midterm while abroad and asked chat for a past exam. It linked a real file:

Summer 2026/.../pastexam/線性代數/2025_midterm_exam1_易志偉_1222.pdf

Clicking it didn't open the PDF.

Steps

  1. In chat, use a bare relative link whose path contains non-ASCII characters, with no ./ prefix.
  2. Click it.

Expected The local file opens.

Actual parseMarkdownFileLink only accepts bare relative paths matching [A-Za-z0-9._-] (packages/client-runtime/src/markdownLinks.ts on main @ 1604ccc). The Chinese characters fail that check, so the link is treated as a web link. Percent-encoding doesn't help, because the path is decoded before the check.

Workaround Prefix the path with ./.

macOS, T3 Code.

Note

Grok responding on behalf of Julius.

Triage

Thanks for the clear report and for already pinpointing the check, @stickerdaniel! I was able to reproduce this on main at 1604ccc.

What I found

  • parseMarkdownFileLink in packages/client-runtime/src/markdownLinks.ts only treats a bare relative path as a file when RELATIVE_FILE_PATH_PATTERN or RELATIVE_FILE_NAME_PATTERN matches. Those allow ASCII tokens (with spaces between them, so docs/My Folder/checklist.xml already works) and reject everything else, so 線性代數 and 易志偉 fail in looksLikeFilePath. A bare filename like 線性代數.pdf fails the same way.
  • safeDecodeURIComponent runs before the check, so a percent-encoded href decodes back to the same characters and is still rejected.
  • Destinations that skip the allowlist (./, ../, ~/, absolute paths, file: URLs) already classify as files, so the ./ workaround is right. Because this path also has spaces, the markdown destination needs angle brackets, e.g. [exam](<./Summer 2026/.../file.pdf>).
  • On web and desktop, when resolveMarkdownFileLinkMeta returns null, ChatMarkdown renders a normal anchor and the click resolves against the app origin. Mobile uses the same parser, and resolveMarkdownLinkPresentation then returns a non-file link with no href, so the text isn't pressable.
  • #16071 touches the same pattern but only to allow #, ?, and % in filenames; it still excludes non-ASCII, so it wouldn't cover this.

Likely fix area

One option is to widen the bare-relative allowlist in packages/client-runtime/src/markdownLinks.ts to accept Unicode letters and numbers (e.g. \p{L}\p{N} with the u flag), which would fix web, desktop, and mobile at once. The trade-off to weigh is how loosely a bare path should be matched before it stops being treated as a web link.

A maintainer will decide on the fix direction.

Synced from GitHub

Confirmed at the parser boundary on #16071's current head, 6d4f26ea667be9c5586855667e40c9ffa560efb2. Calling the exported parseMarkdownFileLink gives:

InputResult
線性代數.pdfnull
線性代數/試卷.pdfnull
%E7%B7%9A%E6%80%A7%E4%BB%A3%E6%95%B8.pdfnull
./線性代數.pdfFile path recognized
report%23final.htmlFile path recognized as report#final.html

The triage comment is correct: #16071 permits decoded #, ?, and % but still rejects Unicode in bare relative paths. It does not fix this issue. Its linked issue #16099 concerns a different stage: a file already recognized and opened in the viewer is shown as source because of the saved HTML preference. Keeping both reports open avoids losing either failure. This check exercised the shared parser directly; it was not a new native-client UI test.

Synced from GitHub

Update: #16071 now includes this fix in 2fa1ef6f24. The two bare-relative path patterns accept Unicode letters, numbers, and combining marks without normalizing the filename. This extends the character handling already changed in that PR.

Eleven new regression checks failed before the extension. The latest focused run passes all 240 shared-parser, web-resolver, and mobile link-presentation tests. Coverage includes the reported Chinese PDF path, encoded links, decomposed accents, combining marks, line targets, and external URL/route exclusions.

In the T3 preview browser, both literal and encoded Unicode HTML links in rendered Markdown opened the document and ran its load script. A Unicode line link opened source with line 3 highlighted. Before/after evidence is in the PR. Native mobile was not tested. This supersedes my earlier comment that the PR did not cover this issue.