mastra-ai/mastra · error
writeFile ${path} failed (exit ${result.exitCode}): ${result
Error message
writeFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()} What it means
writeFile throws this generic Error when the sandbox shell command exits with a non-zero code that is not the EXIT_EXISTS sentinel — i.e. the write failed for a reason other than 'file already exists'. The message carries the path, exit code, and stderr from the failed shell command.
Source
Thrown at mastracode/sdk/src/agents/sandbox-filesystem.ts:281
}
return buffer;
}
async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {
const abs = await this.resolveAsync(path);
await this.assertContainedDest(abs, path);
const b64 = toBuffer(content).toString('base64');
const dir = posixPath.dirname(abs);
const mkdir = options?.recursive === false ? '' : `mkdir -p ${shellQuote(dir)} && `;
if (options?.overwrite === false) {
// `set -C` (noclobber) makes the redirect itself the exclusivity check —
// no exists() pre-check that could race with a concurrent writer.
const result = await this.exec(
`${mkdir}{ (set -C; printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(abs)}) 2>/dev/null || { [ -e ${shellQuote(abs)} ] && exit ${EXIT_EXISTS} || exit 1; }; }`,
);
if (result.exitCode === EXIT_EXISTS) throw new FileExistsError(path);
if (result.exitCode !== 0) {
throw new Error(`writeFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
}
return;
}
await this.execOk(`${mkdir}printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(abs)}`, `writeFile ${path}`);
}
async appendFile(path: string, content: FileContent): Promise<void> {
const abs = await this.resolveAsync(path);
await this.assertContainedDest(abs, path);
const b64 = toBuffer(content).toString('base64');
await this.execOk(
`mkdir -p ${shellQuote(posixPath.dirname(abs))} && printf %s ${shellQuote(b64)} | base64 -d >> ${shellQuote(abs)}`,
`appendFile ${path}`,
);
}
async deleteFile(path: string, options?: RemoveOptions): Promise<void> {
const abs = await this.resolveAsync(path);View on GitHub (pinned to 75dd419e61)
Solutions
- Read the stderr portion of the message to identify the concrete shell failure (mkdir vs base64 vs redirect).
- Verify the destination path is a file path, not a directory, and each parent component is a directory.
- Check sandbox disk space/quota (df) if the failure is 'No space left on device'.
- Ensure the sandbox user has write permission on the target directory, or recreate the workspace.
- Retry the operation — transient sandbox or volume errors can cause one-off failures.
Example fix
// before\nawait fs.writeFile('out/data.txt', buf);\n// after\ntry {\n await fs.writeFile('out/data.txt', buf);\n} catch (e) {\n if (e instanceof Error && e.message.includes('Is a directory')) {\n await fs.deleteFile('out/data.txt', { force: true });\n await fs.writeFile('out/data.txt', buf);\n } else throw e;\n} Defensive patterns
Strategy: retry
Validate before calling
// Verify destination is writable and parents are directories\nconst entries = await fs.readDirectory(posix.dirname(destPath));\nif (entries.directories.every(d => d.path !== posix.basename(destPath)) === false) {\n throw new Error('destination is a directory');\n} Type guard
function isWriteFailureError(e: unknown): boolean {\n return e instanceof Error && /^writeFile .* failed \\(exit/.test(e.message);\n} Try / catch
try {\n await fs.writeFile(path, content);\n} catch (e) {\n if (e instanceof Error && /ENOSPC|No space left/.test(e.message)) {\n // free space or fail fast\n } else if (e instanceof Error && e.message.includes('failed (exit')) {\n // log stderr from message; retry once\n }\n throw e;\n} Prevention
- Ensure target paths are files, never directories.
- Keep parent path components as directories (no file/dir name collisions).
- Monitor sandbox disk usage for quota exhaustion.
- Use default recursive mkdir (don't set recursive:false unless parents exist).
When it happens
Trigger: writeFile where mkdir -p on the parent directory fails (permission denied or parent is a file); base64 -d failing on the pipeline; the destination being an existing directory; noclobber create failing for reasons besides existence; disk-full on the sandbox volume.
Common situations: Passing a directory as the write path; the parent path component being a regular file (e.g. writing 'a/b' where 'a' is a file); sandbox volume quota exhausted; restrictive umask/ownership after container restarts.
Related errors
- Unable to verify path stays within workspace root: ${inputPa
- ${context} failed (exit ${result.exitCode}): ${result.stderr
- readFile ${path} failed (exit ${result.exitCode}): ${result.
- Directory not empty or not found: ${path}
- Invalid environment variable name: "${key}"
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4547efc701d1c366.
Report an issue: GitHub.