mastra-ai/mastra · error

Nested mount paths are not supported: "${b}" is nested under

Error message

Nested mount paths are not supported: "${b}" is nested under "${a}"

What it means

CompositeFilesystem resolves a path to exactly one mount by longest-prefix match; if one mount path is nested under another (e.g., '/data' and '/data/sub'), resolution would be ambiguous. The constructor therefore rejects any mount path that starts with another mount path + '/'. This keeps path dispatch deterministic.

Source

Thrown at packages/core/src/workspace/filesystem/composite-filesystem.ts:112

    for (const [path, fs] of Object.entries(config.mounts)) {
      const normalized = this.normalizePath(path);
      this._mounts.set(normalized, fs);
    }

    if (this._mounts.size === 0) {
      throw new Error('CompositeFilesystem requires at least one mount');
    }

    // Composite is read-only when every mount is read-only
    this.readOnly = [...this._mounts.values()].every(fs => fs.readOnly) || undefined;

    // Validate no nested mount paths (e.g., /data and /data/sub)
    const mountPaths = [...this._mounts.keys()];
    for (const a of mountPaths) {
      for (const b of mountPaths) {
        if (a !== b && b.startsWith(a + '/')) {
          throw new Error(`Nested mount paths are not supported: "${b}" is nested under "${a}"`);
        }
      }
    }
  }

  /**
   * Get all mount paths.
   */
  get mountPaths(): string[] {
    return Array.from(this._mounts.keys());
  }

  /**
   * Get the mounts map.
   * Returns a typed map where `get()` preserves the concrete filesystem type per mount path.
   */
  get mounts(): ReadonlyMountMap<TMounts> {
    return this._mounts as unknown as ReadonlyMountMap<TMounts>;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Flatten the mounts so each top-level prefix is unique; merge the nested backend's files into the parent mount.
  2. Move the nested mount to a sibling path (e.g., '/data' and '/data-sub').
  3. If you need '/' mounted, make it the only mount, or use non-overlapping top-level prefixes.
  4. Validate mount paths for prefix collisions in config loading before constructing the composite.

Example fix

// before
new CompositeFilesystem({ mounts: { '/data': fsA, '/data/sub': fsB } });
// after
new CompositeFilesystem({ mounts: { '/data': fsA, '/uploads/sub': fsB } }); // non-overlapping prefixes
Defensive patterns

Strategy: validation

Validate before calling

const paths = Object.keys(mounts).map(p => p.replace(/\/+$/, ''));
for (const a of paths) for (const b of paths) {
  if (a !== b && b.startsWith(a + '/')) throw new Error(`Mount ${b} is nested under ${a}`);
}

Try / catch

try { new CompositeFilesystem({ mounts }); } catch (e) { if ((e as Error).message.includes('Nested mount paths')) { console.error('Fix mount prefixes; they must not overlap:', e.message); } throw e; }

Prevention

When it happens

Trigger: new CompositeFilesystem({ mounts: { '/data': fsA, '/data/sub': fsB } }) or any mount set where one normalized path is a prefix of another.

Common situations: Merging mount maps from multiple config sources that share base directories; auto-generating mounts per feature folder under a common root; mounting '/' (root) together with any other path — every other mount is nested under '/'.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/89041b40541a1de6. Report an issue: GitHub.