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
- Inspect err.errors (AggregateError) to identify which mounts failed and fix each underlying teardown error.
- Retry destroy() for the failed mounts only, if their backends support re-teardown.
- Check network connectivity/credentials for remote mounts before shutdown.
- 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
- Call destroy() exactly once; guard with a status check.
- Close network connections to remote mounts before shutdown when possible.
- Log AggregateError.errors to spot chronically failing mounts.
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
- CompositeFilesystem requires at least one mount
- Nested mount paths are not supported: "${b}" is nested under
- EACCES
- No mount for path: ${path}
- READ_ONLY
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/9a0b9356a1023b8a.
Report an issue: GitHub.