mastra-ai/mastra · error

No mount for source: ${src}

Error message

No mount for source: ${src}

What it means

CompositeFilesystem routes every operation to a mounted filesystem by matching the path prefix against configured mount points (e.g. '/local', '/s3'). This error is thrown by copyFile when the SOURCE path does not resolve to any mount. The library throws it instead of guessing a backend, because it has no filesystem to read the source file from.

Source

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

  async appendFile(path: string, content: FileContent): Promise<void> {
    const r = this.resolveMount(path);
    if (!r) throw new Error(`No mount for path: ${path}`);
    this.assertWritable(r.fs, path, 'appendFile');
    return r.fs.appendFile(r.fsPath, content);
  }

  async deleteFile(path: string, options?: RemoveOptions): Promise<void> {
    const r = this.resolveMount(path);
    if (!r) throw new Error(`No mount for path: ${path}`);
    this.assertWritable(r.fs, path, 'deleteFile');
    return r.fs.deleteFile(r.fsPath, options);
  }

  async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {
    const srcR = this.resolveMount(src);
    const destR = this.resolveMount(dest);
    if (!srcR) throw new Error(`No mount for source: ${src}`);
    if (!destR) throw new Error(`No mount for dest: ${dest}`);
    this.assertWritable(destR.fs, dest, 'copyFile');

    // Same mount - delegate
    if (srcR.mountPath === destR.mountPath) {
      return srcR.fs.copyFile(srcR.fsPath, destR.fsPath, options);
    }

    // Cross-mount copy - read then write
    const content = await srcR.fs.readFile(srcR.fsPath);
    await destR.fs.writeFile(destR.fsPath, content, { overwrite: options?.overwrite });
  }

  async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {
    const srcR = this.resolveMount(src);
    const destR = this.resolveMount(dest);
    if (!srcR) throw new Error(`No mount for source: ${src}`);
    if (!destR) throw new Error(`No mount for dest: ${dest}`);

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Fix the source path so it starts with an existing mount path (check fs.mountPaths).
  2. Register a mount for the missing prefix in the CompositeFilesystem config, or a root '/' mount as fallback.
  3. Validate the source prefix with composite.getMountPathForPath(src) or getFilesystemForPath(src) before calling copyFile.

Example fix

// before
await cfs.copyFile('report.pdf', '/local/report.pdf');
// after
await cfs.copyFile('/local/report.pdf', '/local/report-copy.pdf');
Defensive patterns

Strategy: validation

Validate before calling

if (!cfs.getMountPathForPath(src)) throw new Error(`Source path '${src}' does not match any mount: ${cfs.mountPaths.join(', ')}`);

Try / catch

try {
  await cfs.copyFile(src, dest);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('No mount for source:')) {
    throw new Error(`Unknown workspace source '${src}'. Available mounts: ${cfs.mountPaths.join(', ')}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling composite.copyFile(src, dest) where src has a prefix (or is not rooted under any) that matches no configured mount key; e.g. mounts are {'/data': ...} but you call copyFile('/other/a.txt', '/data/b.txt') or copyFile('a.txt', '/data/b.txt') without a default/root mount.

Common situations: Mount keys renamed or added after code was written (e.g. '/files' became '/data'); forgetting that the composite only exposes mount-prefixed paths; typos or missing leading slash; a mount removed during refactor; building paths by string concatenation that drops the mount prefix.

Related errors


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