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

  1. If writes are intended, set readOnly: false on the workspace filesystem configuration and redeploy.
  2. Otherwise redirect the write to a different, writable workspace.
  3. 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

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.