microsoft/typescript-go · error
invalid file URI: ${uri}
Error message
invalid file URI: ${uri} What it means
documentURIToFileName parses 'file://' URIs with the WHATWG URL constructor. If URL construction fails — malformed percent-encoding, invalid host characters, or a URL the parser rejects — the catch block rethrows as 'invalid file URI'. The library throws instead of returning garbage because a bad file URI would silently corrupt path round-tripping.
Source
Thrown at _packages/native-preview/src/api/path.ts:509
* documentURIToFileName("file:///path/to/file.ts") === "/path/to/file.ts"
* documentURIToFileName("file:///c%3A/path/to/file.ts") === "c:/path/to/file.ts"
* documentURIToFileName("untitled:Untitled-1") === "^/untitled/ts-nul-authority/Untitled-1"
* documentURIToFileName("vscode-vfs://github/microsoft/typescript-go/file.ts") === "^/vscode-vfs/github/microsoft/typescript-go/file.ts"
*/
export function documentURIToFileName(uri: string): string {
// Bundled files are returned as-is
if (isBundled(uri)) {
return uri;
}
// Handle file:// URIs
if (uri.startsWith("file://")) {
let parsed: URL;
try {
parsed = new URL(uri);
}
catch {
throw new Error("invalid file URI: " + uri);
}
// UNC path: file://server/share/...
if (parsed.host !== "") {
return "//" + parsed.host + parsed.pathname;
}
// Local file - fix Windows path by removing leading slash before volume
const path = decodeURIComponent(parsed.pathname);
if (path.length >= 3 && path.charCodeAt(0) === CharacterCodesSlash) {
const [volume, rest, ok] = splitVolumePath(path.substring(1));
if (ok) {
return volume + rest;
}
}
return path;
}
View on GitHub (pinned to 1bcfa18d79)
Solutions
- Percent-encode each path segment before building the URI (the library's own fileNameToDocumentURI does this via encodeURIComponent)
- Run new URL(uri) in a try/catch yourself first to give a better error
- Replace literal backslashes and raw special characters ('#','?','%', space) with their encoded forms
Example fix
// before
documentURIToFileName("file:///C:/My Files/a%b.ts"); // '%b' is bad encoding -> throws
// after
documentURIToFileName("file:///C:/My%20Files/a%25b.ts"); Defensive patterns
Strategy: validation
Validate before calling
const isParsableFileUri = (uri: string) => {
if (!uri.startsWith("file://")) return true;
try { new URL(uri); return true; } catch { return false; }
}; Try / catch
try { name = documentURIToFileName(uri); } catch (e) { if ((e as Error).message.startsWith("invalid file URI")) { uri = encodeURI(uri); name = documentURIToFileName(uri); } else throw e; } Prevention
- Encode every path segment (encodeURIComponent) before prefixing 'file://'
- Validate file URIs with new URL() before passing them in
- Do not paste raw Windows paths ('C:\', spaces, '#') into a file URI unescaped
When it happens
Trigger: Passing a string that starts with 'file://' but is not parseable by new URL(): 'file://%zz', 'file://C|/path', 'file://' + raw unencoded unicode/pipe characters, or double-encoded strings where '%' survives unescaped.
Common situations: Concatenating 'file://' + windowsPath without encodeURIComponent (pipes, spaces, non-ASCII break URL); receiving URIs from LSP clients that send raw paths; copy/paste of URIs with literal backslashes or unencoded '#'/'?'.
Related errors
- invalid file name: ${fileName}
- invalid URI: ${uri}
- %w: source file not found: %v
- Invalid value for ${name}: ${value}
- Found external imports in .d.ts files:\n${importErrors.map(e
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/a4f61d2eba5c709a.
Report an issue: GitHub.