microsoft/typescript-go · error
Invalid file path: "${path}"
Error message
Invalid file path: "${path}" What it means
Thrown by addToTree in createVirtualFileSystem when a path has zero path components after normalization (getPathComponents(path).slice(1).length === 0), i.e., the path denotes the virtual root itself. Only concrete files can be added, so keys like "" or "/" (or anything that normalizes to the root) are rejected.
Source
Thrown at _packages/native-preview/src/api/fs.ts:96
function ensureDirectory(segments: string[]): VDirectory {
let current: VDirectory = root;
for (const segment of segments) {
if (!current.children[segment]) {
current.children[segment] = { type: "directory", children: {} };
}
else if (current.children[segment].type !== "directory") {
throw new Error(`Cannot create directory: a file already exists at "/${segments.join("/")}"`);
}
current = current.children[segment] as VDirectory;
}
return current;
}
function addToTree(path: string): void {
const segments = getPathComponents(path).slice(1);
if (segments.length === 0) {
throw new Error(`Invalid file path: "${path}"`);
}
const filename = segments.pop()!;
const dirNode = ensureDirectory(segments);
dirNode.children[filename] = { type: "file" };
}
function writeFile(path: string, data: string): void {
content[path] = data;
addToTree(path);
}
function removeFile(path: string): void {
delete content[path];
const segments = getPathComponents(path).slice(1);
if (segments.length === 0) return;
const filename = segments.pop()!;
const dirNode = getNodeFromPath("/" + segments.join("/"));
if (dirNode && dirNode.type === "directory") {
View on GitHub (pinned to 1bcfa18d79)
Solutions
- Filter degenerate keys before constructing the virtual FS: skip empty strings and paths equal to "/"
- Fix the path-construction bug that yields an empty/root path (check for undefined segments in joins)
- Validate in the writeFile callback that the incoming path names a file, and ignore/log root writes
Example fix
// before
const vfs = createVirtualFileSystem({ "": "", "/a.ts": "x" }); // '' -> throws
// after
const files = { "/a.ts": "x" };
for (const k of Object.keys(files)) {
if (!k || k === "/") delete files[k]; // drop root/empty entries
}
const vfs = createVirtualFileSystem(files); Defensive patterns
Strategy: validation
Validate before calling
// Drop root/empty keys before constructing the virtual FS
const clean: Record<string, string> = {};
for (const [p, content] of Object.entries(files)) {
const norm = p.replace(/\\/g, '/');
if (!norm || norm === '/') continue; // cannot add the root itself
clean[norm] = content;
}
const vfs = createVirtualFileSystem(clean); Type guard
const isVirtualFilePath = (p: string): boolean => {
const norm = p.replace(/\\/g, '/');
return norm.length > 1 && norm.startsWith('/') && norm !== '/';
}; Try / catch
try {
vfs.writeFile(path, data);
} catch (e) {
if (e instanceof Error && e.message.includes('Invalid file path')) {
// caller sent a root/empty path - log and ignore rather than crash the callback
console.warn('writeFile rejected invalid path:', JSON.stringify(path));
} else throw e;
} Prevention
- Assert every path names a concrete file under a directory before insertion
- Check join() results for empty segments when building paths dynamically
- In writeFile callbacks from the server, validate before mutating the tree
When it happens
Trigger: Including "" or "/" as a key in the files map passed to createVirtualFileSystem; the server's writeFile callback sending an empty or root path; dynamically built paths where a join produced an empty string.
Common situations: Fixture builders that insert a placeholder key for the root; typos or undefined interpolation producing empty strings in path maps; logging/harness code that mirrors every observed path including the workspace root.
Related errors
- Cannot create directory: a file already exists at "/${segmen
- Cannot run a temporary file update on an inactive snapshot
- Snapshot is disposed
- Bad line number. Line: ${line}, lineStarts.length: ${lineSta
- Expected ${pkgName} to declare exactly one bin entry named $
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/3ae81514dc0d3224.
Report an issue: GitHub.