[Bug] Windows: /insights emits a malformed file:// report URL (file://C:\... instead of file:///C:/...)

Status Open
Reported on v2.1.251
Maintainer reply None cached
Activity 0 comments · opened Aug 30, 2026

Bug Description

On Windows, /insights builds the report link by concatenating file:// with the raw native path, so the printed link is:

file://C:\Users\<me>\.claude\usage-data\report-2026-08-30-093417.html

Two defects in one string:

  1. Only two slashes — the drive letter C: lands in the URL's authority/host slot instead of the path.
  2. Backslash separators, which are not valid URL path separators.

The canonical form is:

file:///C:/Users/<me>/.claude/usage-data/report-2026-08-30-093417.html

Why it matters: terminal and UI linkifiers stop at the first backslash, so the link isn't clickable and pasting it elsewhere doesn't open the report. Strict WHATWG URL parsers happen to recover the string (see Verification), which is probably why this has gone unnoticed — but the raw text is what reaches the renderer.

Source

In the bundled CLI (native installer, versions/2.1.251), the /insights builtin constructs the URL by string concatenation:

let { insights: c, htmlPath: d, data: r, remoteStats: l } = await gt({ ... }),
    a = `file://${d}`;   // d is a native Windows path

a is then interpolated into the response template as Report URL: and, more importantly, as the literal line the model is instructed to echo verbatim:

Respond with exactly the following, and nothing else. Do not add, omit, or reword any line:

Your shareable insights report is ready:
${s}

so the malformed URL is exactly what the user sees, with no opportunity to normalize it.

Steps to Reproduce

  1. On Windows, run /insights.
  2. Observe the printed file://... link — not clickable, and doesn't resolve when copied.

Verification

$ node -e "<construct 'file://' + windows path, parse, compare to pathToFileURL>"
raw    : file://C:\Users\me\.claude\usage-data\report.html
href   : file:///C:/Users/me/.claude/usage-data/report.html
host   : ""
correct: file:///C:/Users/me/.claude/usage-data/report.html

new URL() normalizes it and fileURLToPath() round-trips correctly — so consumers that run it through a real URL parser are fine. The problem is purely the emitted text.

Suggested Fix

Use pathToFileURL instead of concatenation:

import { pathToFileURL } from "node:url";
const a = pathToFileURL(d).href;

This is also correct on POSIX, and additionally percent-encodes spaces and non-ASCII characters in the path (cf. #90336, where such paths break links).

Environment Info

  • Platform: win32 (Windows 11, 10.0.26200.9168)
  • Terminal: Claude Code CLI (native install)
  • Version: 2.1.251

Related but distinct: #81252 reports a missing separator in this same command's path output (C:\Users\jagbe.claude\...), which looks like the markdown-escape swallowing of \. tracked in #88952 — a different root cause from this URL-construction bug, though both surface on the /insights output line.

View original on GitHub ↗