mastra-ai/mastra · error · WorkspaceReadOnlyError

READ_ONLY

READ_ONLY

Error message

Workspace is in read-only mode. Cannot perform: edit_file

What it means

Thrown by the edit-file workspace tool when the filesystem is read-only. Editing a file (read + replace) mutates the workspace, so the tool throws WorkspaceReadOnlyError with code READ_ONLY before reading the file.

Source

Thrown at packages/core/src/workspace/tools/edit-file.ts:62

      .boolean()
      .optional()
      .default(false)
      .describe('If true, replace all occurrences. If false (default), old_string must be unique.'),
  }),
  execute: async ({ path, old_string, new_string, replace_all }, context) => {
    const { workspace, filesystem } = requireFilesystem(context);
    await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE);

    const span = startWorkspaceSpan(context, workspace, {
      category: 'filesystem',
      operation: 'editFile',
      input: { path, replace_all },
      attributes: { filesystemProvider: filesystem.provider },
    });

    try {
      if (filesystem.readOnly) {
        throw new WorkspaceReadOnlyError('edit_file');
      }

      const content = await filesystem.readFile(path, { encoding: 'utf-8' });

      if (typeof content !== 'string') {
        span.end({ success: false });
        return `Cannot edit binary files. Use the write file tool instead.`;
      }

      const shouldReplaceAll = replace_all ?? false;
      const lineRanges = getEditedLineRanges(content, old_string, new_string, shouldReplaceAll);
      const result = replaceString(content, old_string, new_string, shouldReplaceAll);
      await filesystem.writeFile(path, result.content, {
        overwrite: true,
        expectedMtime: (context as any)?.__expectedMtime,
      });

      let output = `Replaced ${result.replacements} occurrence${result.replacements !== 1 ? 's' : ''} in ${path}${lineRanges}`;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Enable write access on the workspace filesystem provider
  2. Copy the project to a writable location and point the workspace there
  3. Remount the volume read-write if the readOnly flag comes from an underlying mount
  4. Catch READ_ONLY and instruct the user/agent that edits are unavailable in this environment

Example fix

// before
new Workspace({ filesystem: getReadOnlyFs() })
// after
new Workspace({ filesystem: getWritableFs(rootDir) })
Defensive patterns

Strategy: validation

Validate before calling

if (workspace.filesystem.readOnly) {
  throw new Error('edit_file unavailable: workspace is read-only');
}

Type guard

function canEdit(fs: WorkspaceFilesystem | undefined): fs is WorkspaceFilesystem & { readOnly: false } {
  return !!fs && fs.readOnly === false;
}

Try / catch

try {
  await editTool.execute({ context: { path, ... }, ... });
} catch (e: any) {
  if (e?.code === 'READ_ONLY') {
    return { error: 'Cannot edit files in a read-only workspace.' };
  }
  throw e;
}

Prevention

When it happens

Trigger: Invoking the edit_file tool (path, search/replace, replace_all) against a workspace with filesystem.readOnly = true.

Common situations: Coding agents connected to read-only checkouts or production mounts; misconfigured deployment where the workspace volume is mounted ro.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/30dbb0e1bdc6caa9. Report an issue: GitHub.