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

  1. Filter degenerate keys before constructing the virtual FS: skip empty strings and paths equal to "/"
  2. Fix the path-construction bug that yields an empty/root path (check for undefined segments in joins)
  3. 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

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


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/3ae81514dc0d3224. Report an issue: GitHub.