microsoft/TypeScript · error · Error

Cannot create a case-insensitive file system from a case-sen

Error message

Cannot create a case-insensitive file system from a case-sensitive one.

What it means

Thrown by FileSystem.shadow (vfsUtil.ts:163) when the caller requests `ignoreCase: true` (case-insensitive) on a source file system that is case-sensitive (ignoreCase === false). A case-insensitive overlay cannot be layered on top of case-sensitive data because name lookups would not match the underlying nodes.

Source

Thrown at src/harness/vfsUtil.ts:163

        const fs = new FileSystem(this.ignoreCase, { time: this._time });
        fs._lazy = this._lazy;
        fs._cwd = this._cwd;
        fs._time = this._time;
        fs._shadowRoot = this._shadowRoot;
        fs._dirStack = this._dirStack;
        fs.makeReadonly();
        this._lazy = {};
        this._shadowRoot = fs;
    }

    /**
     * Gets a shadow copy of this file system. Changes to the shadow copy do not affect the
     * original, allowing multiple copies of the same core file system without multiple copies
     * of the same data.
     */
    public shadow(ignoreCase: boolean = this.ignoreCase): FileSystem {
        if (!this.isReadonly) throw new Error("Cannot shadow a mutable file system.");
        if (ignoreCase && !this.ignoreCase) throw new Error("Cannot create a case-insensitive file system from a case-sensitive one.");
        const fs = new FileSystem(ignoreCase, { time: this._time });
        fs._shadowRoot = this;
        fs._cwd = this._cwd;
        return fs;
    }

    /**
     * Gets or sets the timestamp (in milliseconds) used for file status, returning the previous timestamp.
     *
     * @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/time.html
     */
    public time(value?: number): number {
        if (value !== undefined) {
            if (this.isReadonly) throw createIOError("EPERM");
            this._time = value;
        }
        else if (!this.isReadonly) {
            this._time += timeIncrements;

View on GitHub (pinned to b465fdbfe1)

Solutions

  1. Construct the base FileSystem with `ignoreCase: true` from the start, then shadow with the default argument.
  2. If the base must remain case-sensitive, do not request a case-insensitive shadow — keep ignoreCase false or build a fresh FS.
  3. Pass `fs.shadow(fs.ignoreCase)` explicitly to inherit rather than forcing true.

Example fix

// before
const base = new FileSystem(false /*case-sensitive*/, {...});
base.makeReadonly();
const fork = base.shadow(true); // throws

// after — build case-insensitive from the source
const base = new FileSystem(true /*case-insensitive*/, {...});
base.makeReadonly();
const fork = base.shadow();
Defensive patterns

Strategy: validation

Validate before calling

// Only request a case-insensitive shadow if the source already is.
const fork = fs.shadow(fs.ignoreCase); // inherit instead of forcing true

Type guard

function canShadowAsCaseInsensitive(fs: FileSystem): boolean {
  return fs.ignoreCase === true;
}

Prevention

When it happens

Trigger: `fs.shadow(true)` is invoked on an FS constructed with `ignoreCase: false`. The default argument to shadow is `this.ignoreCase`, so this only fires when the caller explicitly passes true.

Common situations: Trying to simulate Windows/macOS behaviour by shadowing a Linux-style case-sensitive base; reusing a case-sensitive fixture for a case-insensitive test; passing a hard-coded `true` for ignoreCase regardless of the source.

Related errors


AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12). Data as JSON: /api/errors/97bd38440def3d3d. Report an issue: GitHub.