{"record":{"id":"6748dc7a06f915c8","repo":"mastra-ai/mastra","slug":"workspace-is-in-read-only-mode","errorCode":null,"errorMessage":"Workspace is in read-only mode","messagePattern":"Workspace is in read-only mode","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"packages/server/src/server/handlers/workspace.ts","lineNumber":541,"sourceCode":"  responseSchema: fsWriteResponseSchema,\n  summary: 'Write file content',\n  description: 'Writes content to a file at the specified path. Supports base64 encoding for binary files.',\n  tags: ['Workspace'],\n  handler: async ({ mastra, path, content, encoding, recursive, workspaceId }) => {\n    try {\n      requireWorkspaceV1Support();\n\n      if (!path || content === undefined) {\n        throw new HTTPException(400, { message: 'Path and content are required' });\n      }\n\n      const workspace = await getWorkspaceById(mastra, workspaceId);\n      if (!workspace?.filesystem) {\n        throw new HTTPException(404, { message: 'No workspace filesystem configured' });\n      }\n\n      if (workspace.filesystem?.readOnly) {\n        throw new HTTPException(403, { message: 'Workspace is in read-only mode' });\n      }\n\n      const decodedPath = decodeURIComponent(path);\n\n      // Handle base64-encoded content for binary files\n      let fileContent: string | Buffer = content;\n      if (encoding === 'base64') {\n        fileContent = Buffer.from(content, 'base64');\n      }\n\n      await workspace.filesystem.writeFile(decodedPath, fileContent, { recursive: recursive ?? true });\n\n      return {\n        success: true,\n        path: decodedPath,\n      };\n    } catch (error) {\n      return handleWorkspaceError(error, 'Error writing file');","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/workspace.ts#L523-L559","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nnew WorkspaceFilesystem({ root: './workspace', readOnly: true });\n// after\nnew WorkspaceFilesystem({ root: './workspace', readOnly: false });","handlingStrategy":"validation","validationCode":"const ws = await getWorkspace(workspaceId);\nif (ws?.safety?.readOnly) {\n  throw new Error(`Workspace ${workspaceId} is read-only; cannot write \"${path}\"`);\n}","typeGuard":"function isWritable(ws: { safety?: { readOnly?: boolean }; filesystem?: unknown } | undefined | null): boolean {\n  return !!ws && ws.filesystem != null && ws.safety?.readOnly !== true;\n}","tryCatchPattern":"try {\n  await writeWorkspaceFile({ workspaceId, path, content });\n} catch (e) {\n  if (isHttpException(e, 403) && e.message.includes('read-only mode')) {\n    logger.warn(`Write to read-only workspace ${workspaceId} skipped`);\n    return { skipped: true, reason: 'read-only' };\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["workspace","http-403","read-only","file-write","forbidden"],"backgroundTag":"read-only-filesystem","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}