{"record":{"id":"4c2bba16fd65d5fe","repo":"microsoft/typescript-go","slug":"invalid-file-name-filename","errorCode":null,"errorMessage":"invalid file name: ${fileName}","messagePattern":"invalid file name: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"_packages/native-preview/src/api/path.ts","lineNumber":451,"sourceCode":" * @example\r\n * fileNameToDocumentURI(\"/path/to/file.ts\") === \"file:///path/to/file.ts\"\r\n * fileNameToDocumentURI(\"c:/path/to/file.ts\") === \"file:///c%3A/path/to/file.ts\"\r\n * fileNameToDocumentURI(\"^/untitled/ts-nul-authority/Untitled-1\") === \"untitled:Untitled-1\"\r\n * fileNameToDocumentURI(\"^/vscode-vfs/github/microsoft/typescript-go/file.ts\") === \"vscode-vfs://github/microsoft/typescript-go/file.ts\"\r\n */\r\nexport function fileNameToDocumentURI(fileName: string): string {\r\n    // Bundled files are returned as-is\r\n    if (isBundled(fileName)) {\r\n        return fileName;\r\n    }\r\n\r\n    // Dynamic/virtual files (untitled, vscode-vfs, etc.) need special handling\r\n    if (isDynamicFileName(fileName)) {\r\n        // Format: ^/scheme/authority/path\r\n        const withoutPrefix = fileName.substring(2); // Remove \"^/\"\r\n        const firstSlash = withoutPrefix.indexOf(\"/\");\r\n        if (firstSlash === -1) {\r\n            throw new Error(\"invalid file name: \" + fileName);\r\n        }\r\n        const scheme = withoutPrefix.substring(0, firstSlash);\r\n        const rest = withoutPrefix.substring(firstSlash + 1);\r\n\r\n        const secondSlash = rest.indexOf(\"/\");\r\n        if (secondSlash === -1) {\r\n            throw new Error(\"invalid file name: \" + fileName);\r\n        }\r\n        const authority = rest.substring(0, secondSlash);\r\n        const path = rest.substring(secondSlash + 1);\r\n\r\n        // ts-nul-authority is a placeholder for URIs without an authority\r\n        if (authority === \"ts-nul-authority\") {\r\n            return scheme + \":\" + path;\r\n        }\r\n        return scheme + \"://\" + authority + \"/\" + path;\r\n    }\r\n\r","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/_packages/native-preview/src/api/path.ts#L433-L469","documentation":"fileNameToDocumentURI converts the internal dynamic-file-name format '^/scheme/authority/path' back into a URI. After stripping the '^/' prefix, it requires at least one '/' so a scheme can be split from the remainder. A name like '^/untitled' (scheme only, nothing after the first slash) has no authority/path component and cannot be mapped to a URI, so it throws.","triggerScenarios":"Calling fileNameToDocumentURI with a dynamic file name that starts with '^/' but contains no '/' after the scheme: '^/untitled', '^/vscode-vfs', '^/memory'. Well-formed inputs like '^/untitled/ts-nul-authority/Untitled-1' pass because they have two slashes.","commonSituations":"Editor integrations constructing dynamic file names by hand instead of round-tripping through documentURIToFileName; string concatenation bugs that drop the authority/path segments; custom virtual file schemes registered without a path part.","solutions":["Ensure dynamic file names use the full format '^/scheme/authority/path' (authority is 'ts-nul-authority' when there is none)","Produce dynamic names via documentURIToFileName(uri) instead of building them manually so they always round-trip","Guard inputs with a regex such as /^\\/[^/]+\\/[^/]+\\// before calling fileNameToDocumentURI"],"exampleFix":"// before\nfileNameToDocumentURI(\"^/untitled\"); // throws: no slash after scheme\n\n// after\nfileNameToDocumentURI(\"^/untitled/ts-nul-authority/Untitled-1\"); // 'untitled:Untitled-1'","handlingStrategy":"validation","validationCode":"const validDynamicName = (f: string) => /^\\^\\/[^/]+\\/[^/]+\\//.test(f);","typeGuard":"function isValidDynamicFileName(f: string): boolean {\n  return !f.startsWith(\"^/\") || /^\\^\\/[^/]+\\/[^/]+\\//.test(f);\n}","tryCatchPattern":"try { uri = fileNameToDocumentURI(name); } catch (e) { if ((e as Error).message.startsWith(\"invalid file name\")) { /* repair name to ^/scheme/authority/path */ } else throw e; }","preventionTips":["Always create dynamic names via documentURIToFileName so they round-trip","Use 'ts-nul-authority' as the authority for authority-less schemes","Validate the '^/scheme/authority/path' shape before converting"],"tags":["typescript","path","uri","validation"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}