{"record":{"id":"a4f61d2eba5c709a","repo":"microsoft/typescript-go","slug":"invalid-file-uri-uri","errorCode":null,"errorMessage":"invalid file URI: ${uri}","messagePattern":"invalid file URI: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"_packages/native-preview/src/api/path.ts","lineNumber":509,"sourceCode":" * documentURIToFileName(\"file:///path/to/file.ts\") === \"/path/to/file.ts\"\r\n * documentURIToFileName(\"file:///c%3A/path/to/file.ts\") === \"c:/path/to/file.ts\"\r\n * documentURIToFileName(\"untitled:Untitled-1\") === \"^/untitled/ts-nul-authority/Untitled-1\"\r\n * documentURIToFileName(\"vscode-vfs://github/microsoft/typescript-go/file.ts\") === \"^/vscode-vfs/github/microsoft/typescript-go/file.ts\"\r\n */\r\nexport function documentURIToFileName(uri: string): string {\r\n    // Bundled files are returned as-is\r\n    if (isBundled(uri)) {\r\n        return uri;\r\n    }\r\n\r\n    // Handle file:// URIs\r\n    if (uri.startsWith(\"file://\")) {\r\n        let parsed: URL;\r\n        try {\r\n            parsed = new URL(uri);\r\n        }\r\n        catch {\r\n            throw new Error(\"invalid file URI: \" + uri);\r\n        }\r\n\r\n        // UNC path: file://server/share/...\r\n        if (parsed.host !== \"\") {\r\n            return \"//\" + parsed.host + parsed.pathname;\r\n        }\r\n\r\n        // Local file - fix Windows path by removing leading slash before volume\r\n        const path = decodeURIComponent(parsed.pathname);\r\n        if (path.length >= 3 && path.charCodeAt(0) === CharacterCodesSlash) {\r\n            const [volume, rest, ok] = splitVolumePath(path.substring(1));\r\n            if (ok) {\r\n                return volume + rest;\r\n            }\r\n        }\r\n        return path;\r\n    }\r\n\r","sourceCodeStart":491,"sourceCodeEnd":527,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/_packages/native-preview/src/api/path.ts#L491-L527","documentation":"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.","triggerScenarios":"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.","commonSituations":"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 '#'/'?'.","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"],"exampleFix":"// before\ndocumentURIToFileName(\"file:///C:/My Files/a%b.ts\"); // '%b' is bad encoding -> throws\n\n// after\ndocumentURIToFileName(\"file:///C:/My%20Files/a%25b.ts\");","handlingStrategy":"validation","validationCode":"const isParsableFileUri = (uri: string) => {\n  if (!uri.startsWith(\"file://\")) return true;\n  try { new URL(uri); return true; } catch { return false; }\n};","typeGuard":null,"tryCatchPattern":"try { name = documentURIToFileName(uri); } catch (e) { if ((e as Error).message.startsWith(\"invalid file URI\")) { uri = encodeURI(uri); name = documentURIToFileName(uri); } else throw e; }","preventionTips":["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"],"tags":["typescript","uri","path","validation"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}