mastra-ai/mastra · error · HTTPException
Workspace is in read-only mode
Error message
Workspace is in read-only mode
What it means
Thrown (HTTP 403) by the workspace file write handler when the workspace filesystem is in read-only mode. The workspace exists and has a filesystem, but it was configured with readOnly: true as a safety measure, so all mutating file operations are refused. This is a deliberate policy denial, not a transient failure — retries will not help until the configuration changes.
Source
Thrown at packages/server/src/server/handlers/workspace.ts:541
responseSchema: fsWriteResponseSchema,
summary: 'Write file content',
description: 'Writes content to a file at the specified path. Supports base64 encoding for binary files.',
tags: ['Workspace'],
handler: async ({ mastra, path, content, encoding, recursive, workspaceId }) => {
try {
requireWorkspaceV1Support();
if (!path || content === undefined) {
throw new HTTPException(400, { message: 'Path and content are required' });
}
const workspace = await getWorkspaceById(mastra, workspaceId);
if (!workspace?.filesystem) {
throw new HTTPException(404, { message: 'No workspace filesystem configured' });
}
if (workspace.filesystem?.readOnly) {
throw new HTTPException(403, { message: 'Workspace is in read-only mode' });
}
const decodedPath = decodeURIComponent(path);
// Handle base64-encoded content for binary files
let fileContent: string | Buffer = content;
if (encoding === 'base64') {
fileContent = Buffer.from(content, 'base64');
}
await workspace.filesystem.writeFile(decodedPath, fileContent, { recursive: recursive ?? true });
return {
success: true,
path: decodedPath,
};
} catch (error) {
return handleWorkspaceError(error, 'Error writing file');View on GitHub (pinned to 75dd419e61)
Solutions
- If writes are intended, set readOnly: false on the workspace filesystem configuration and redeploy.
- Otherwise redirect the write to a different, writable workspace.
- Check the workspace safety config (readOnly flag on the workspace list endpoint) before enabling auto-write tooling.
Example fix
// before
new WorkspaceFilesystem({ root: './workspace', readOnly: true });
// after
new WorkspaceFilesystem({ root: './workspace', readOnly: false }); Defensive patterns
Strategy: validation
Validate before calling
const ws = await getWorkspace(workspaceId);
if (ws?.safety?.readOnly) {
throw new Error(`Workspace ${workspaceId} is read-only; cannot write "${path}"`);
} Type guard
function isWritable(ws: { safety?: { readOnly?: boolean }; filesystem?: unknown } | undefined | null): boolean {
return !!ws && ws.filesystem != null && ws.safety?.readOnly !== true;
} Try / catch
try {
await writeWorkspaceFile({ workspaceId, path, content });
} catch (e) {
if (isHttpException(e, 403) && e.message.includes('read-only mode')) {
logger.warn(`Write to read-only workspace ${workspaceId} skipped`);
return { skipped: true, reason: 'read-only' };
}
throw e;
} Prevention
- Read the workspace safety.readOnly flag before configuring auto-writers.
- Route writes for read-only workspaces to a designated writable workspace.
- Do not retry on 403 read-only — it is a policy denial, not transient.
- Keep environment promotion scripts from copying readOnly flags unintentionally.
When it happens
Trigger: POST/PUT file writes against a workspace whose filesystem was created with readOnly: true — e.g. production workspaces locked for safety, inspection/demo workspaces, or a shared filesystem flagged read-only after a safety incident.
Common situations: Dev tools that auto-write (formatters, codegen) pointed at a read-only production workspace; forgetting that readOnly applies to the whole filesystem including writes via the server API; environment promotion copying a read-only flag along.
Related errors
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/6748dc7a06f915c8.
Report an issue: GitHub.