mastra-ai/mastra · error · WorkspaceReadOnlyError
READ_ONLY
READ_ONLY
Error message
Workspace is in read-only mode. Cannot perform: write_file
What it means
The `writeFile` tool refuses to write when the workspace filesystem is read-only. Before calling `filesystem.writeFile`, it checks `filesystem.readOnly` and throws `WorkspaceReadOnlyError('write_file')`. This protects read-only mounted workspaces from any mutation via agent tools.
Source
Thrown at packages/core/src/workspace/tools/write-file.ts:30
inputSchema: z.object({
path: z.string().describe('The path where to write the file (e.g., "data/output.txt")'),
content: z.string().describe('The content to write to the file'),
overwrite: z.boolean().optional().default(true).describe('Whether to overwrite the file if it already exists'),
}),
execute: async ({ path, content, overwrite }, context) => {
const { workspace, filesystem } = requireFilesystem(context);
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE);
const span = startWorkspaceSpan(context, workspace, {
category: 'filesystem',
operation: 'writeFile',
input: { path, overwrite, contentLength: content.length },
attributes: { filesystemProvider: filesystem.provider },
});
try {
if (filesystem.readOnly) {
throw new WorkspaceReadOnlyError('write_file');
}
await filesystem.writeFile(path, content, {
overwrite,
expectedMtime: (context as any)?.__expectedMtime,
});
const size = Buffer.byteLength(content, 'utf-8');
let output = `Wrote ${size} bytes to ${path}`;
output += await getEditDiagnosticsText(workspace, path, content);
span.end({ success: true }, { bytesTransferred: size });
return output;
} catch (err) {
span.error(err);
throw err;
}
},
});View on GitHub (pinned to 75dd419e61)
Solutions
- Construct the filesystem with read-only disabled if writes are intended
- Remove write_file (and other mutators) from the tools config for read-only workspaces
- Persist intended changes elsewhere (e.g. output a patch) and apply them outside the read-only workspace
Example fix
// before
new LocalFilesystem('/mnt/readonly', { readOnly: true }) // write_file tool enabled
// after
new LocalFilesystem('/mnt/readonly', { readOnly: true })
// tools: only read tools enabled for this workspace Defensive patterns
Strategy: validation
Validate before calling
if (filesystem.readOnly) {
throw new Error('write_file cannot be used on a read-only workspace.');
} Try / catch
try {
await writeFileTool.execute({ path, content }, ctx);
} catch (err) {
if (err?.code === 'READ_ONLY') {
return { error: 'Workspace is read-only; produce a diff/patch instead.' };
}
throw err;
} Prevention
- Exclude write_file and other mutators from tools config whenever readOnly is true
- State read-only constraints in the agent system prompt
- Test workspace setups: assert no write tools registered for readOnly filesystems
When it happens
Trigger: Calling the `write_file` workspace tool while `filesystem.readOnly === true`, including with `overwrite: true` — the check happens before any write attempt.
Common situations: Agents attached to a read-only snapshot or prod mount; the `expectedMtime` concurrency mechanism irrelevant because writes are disallowed entirely; forgetting to disable write tools on read-only workspaces.
Related errors
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/9c4358e1e499e358.
Report an issue: GitHub.