mastra-ai/mastra · error

CompositeFilesystem requires at least one mount

Error message

CompositeFilesystem requires at least one mount

What it means

CompositeFilesystem aggregates multiple mounted filesystems under path prefixes; it requires config.mounts to contain at least one entry. With zero mounts, no path could ever resolve, so the constructor fails fast instead of producing a filesystem where every operation errors. It is raised in the constructor, so the object is never created.

Source

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

  readonly name = 'CompositeFilesystem';
  readonly provider = 'composite';

  readonly readOnly?: boolean;
  status: ProviderStatus = 'ready';

  private readonly _mounts: Map<string, WorkspaceFilesystem>;

  constructor(config: CompositeFilesystemConfig<TMounts>) {
    this.id = `cfs-${Date.now().toString(36)}`;
    this._mounts = new Map();

    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.

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass at least one mount, e.g. { mounts: { '/': new LocalFilesystem('/data') } }.
  2. Log/inspect the mounts object passed to the constructor; fix the config source that produced an empty map.
  3. If mounts are dynamic, guard construction: only create the composite after confirming at least one backend is available.

Example fix

// before
new CompositeFilesystem({ mounts: {} });
// after
const mounts = loadMountsFromConfig();
if (Object.keys(mounts).length === 0) throw new Error('No workspace mounts configured');
new CompositeFilesystem({ mounts });
Defensive patterns

Strategy: validation

Validate before calling

if (!mounts || Object.keys(mounts).length === 0) {
  throw new Error('CompositeFilesystem config.mounts must contain at least one entry');
}
const composite = new CompositeFilesystem({ mounts });

Type guard

function hasMounts(cfg: unknown): cfg is { mounts: Record<string, WorkspaceFilesystem> } {
  return typeof cfg === 'object' && cfg !== null && 'mounts' in cfg &&
    typeof (cfg as any).mounts === 'object' && Object.keys((cfg as any).mounts).length > 0;
}

Try / catch

let fs: CompositeFilesystem;
try { fs = new CompositeFilesystem({ mounts }); } catch (e) { if ((e as Error).message.includes('at least one mount')) { fs = new CompositeFilesystem({ mounts: { '/': fallbackFs } }); } else throw e; }

Prevention

When it happens

Trigger: Constructing new CompositeFilesystem({ mounts: {} }) or with a mounts object that is empty, or where all entries are filtered out before mounting (empty normalized keys).

Common situations: Building mounts from an environment variable or config file that parsed to an empty object; conditional mounting logic that skipped all backends; typo in the config key holding mount definitions.

Related errors


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