mastra-ai/mastra · error · AggregateError

Some filesystems failed to destroy

Error message

Some filesystems failed to destroy

What it means

destroy() tears down every mounted filesystem; individual failures are collected and thrown together as an AggregateError with this message. Some mounts were destroyed, others failed, and the composite's status is set to 'error'. The error carries the per-mount errors in its `errors` array for diagnosis.

Source

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

    }
    // CompositeFilesystem is ready even if some mounts failed
    // Operations on errored mounts will be handled by the underlying filesystem
    this.status = 'ready';
  }

  async destroy(): Promise<void> {
    this.status = 'destroying';
    const errors: Error[] = [];
    for (const fs of this._mounts.values()) {
      try {
        await callLifecycle(fs, 'destroy');
      } catch (e) {
        errors.push(e instanceof Error ? e : new Error(String(e)));
      }
    }
    if (errors.length > 0) {
      this.status = 'error';
      throw new AggregateError(errors, 'Some filesystems failed to destroy');
    }
    this.status = 'destroyed';
  }

  async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {
    const r = this.resolveMount(path);
    if (!r) throw new Error(`No mount for path: ${path}`);
    return r.fs.readFile(r.fsPath, options);
  }

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

  async appendFile(path: string, content: FileContent): Promise<void> {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Inspect err.errors (AggregateError) to identify which mounts failed and fix each underlying teardown error.
  2. Retry destroy() for the failed mounts only, if their backends support re-teardown.
  3. Check network connectivity/credentials for remote mounts before shutdown.
  4. Ensure destroy() is called once per composite; guard against double-destroy by checking status.

Example fix

// before
await composite.destroy();
// after
try { await composite.destroy(); }
catch (e) {
  if (e instanceof AggregateError) for (const sub of e.errors) console.error('mount destroy failed:', sub);
  throw e;
}
Defensive patterns

Strategy: try-catch

Type guard

function isAggregateError(e: unknown): e is AggregateError { return e instanceof AggregateError && Array.isArray(e.errors); }

Try / catch

try { await composite.destroy(); } catch (e) {
  if (e instanceof AggregateError) {
    for (const sub of e.errors) console.error('Mount teardown failed:', sub);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling composite.destroy() when one or more mounts' own destroy() rejects — e.g., a remote filesystem failing to close connections, or a local fs failing to release watchers/locks.

Common situations: Shutting down a server whose workspace mounts include flaky network backends; double-destroy (second call hits already-closed resources); timeouts closing remote storage sessions.

Related errors


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