mastra-ai/mastra · error · WorkspaceReadOnlyError
READ_ONLY
READ_ONLY
Error message
Workspace is in read-only mode. Cannot perform: ast_edit
What it means
Thrown by the ast_edit workspace tool when the workspace filesystem is in read-only mode. AST-based code transformations mutate files, so they are blocked before loading ast-grep. The error carries code READ_ONLY via WorkspaceReadOnlyError with the offending operation name.
Source
Thrown at packages/core/src/workspace/tools/ast-edit.ts:448
isDefault: z.boolean().optional().describe('Whether the first name is a default import'),
})
.optional()
.describe('Required for add-import transform. Specifies the module and names to import.'),
}),
execute: async ({ path, pattern, replacement, transform, targetName, newName, importSpec }, context) => {
const { workspace, filesystem } = requireFilesystem(context);
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.AST_EDIT);
const span = startWorkspaceSpan(context, workspace, {
category: 'filesystem',
operation: 'astEdit',
input: { path, transform, pattern },
attributes: { filesystemProvider: filesystem.provider },
});
try {
if (filesystem.readOnly) {
throw new WorkspaceReadOnlyError('ast_edit');
}
// Load ast-grep (cached after first call)
const astGrep = await loadAstGrep();
if (!astGrep) {
span.end({ success: false });
return '@ast-grep/napi is not available. Install it to use AST editing.';
}
const { parse, Lang } = astGrep;
// Read current content
let content: string | Buffer;
try {
content = await filesystem.readFile(path, { encoding: 'utf-8' });
} catch (error) {
if (error instanceof FileNotFoundError) {
span.end({ success: false });
return `File not found: ${path}. Use the write file tool to create it first.`;View on GitHub (pinned to 75dd419e61)
Solutions
- Configure the workspace filesystem as writable (remove readOnly / supply a writable provider)
- Mount or point the workspace at a writable copy of the files instead of a read-only source
- Skip ast_edit in read-only deployments and surface file changes through a separate write workflow
- Check workspace.filesystem read-only status before invoking edit tools to fail gracefully
Example fix
// before
new Workspace({ filesystem: createFilesystem({ root, readOnly: true }) });
// after
new Workspace({ filesystem: createFilesystem({ root, readOnly: false }) }); Defensive patterns
Strategy: validation
Validate before calling
if (workspace.filesystem && workspace.filesystem.readOnly) {
throw new Error('ast_edit 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 astEditTool.execute({ context: { path, transform, pattern }, ... });
} catch (e: any) {
if (e?.code === 'READ_ONLY' || /read-only mode/i.test(e?.message ?? '')) {
return { skipped: true, reason: 'workspace is read-only' };
}
throw e;
} Prevention
- Check filesystem.readOnly before registering mutation tools
- Provision writable workspaces for editing agents
- Run code-edit agents against writable clones, not production mounts
- Surface read-only status in agent instructions/UI
When it happens
Trigger: Invoking the ast_edit tool (with path, transform, pattern inputs) on a workspace whose filesystem provider was configured read-only, or whose readOnly flag is true at execution time.
Common situations: Running agents against a read-only workspace/deployment (e.g. production inspection, sandboxed preview); forgetting to enable write access for an editing agent.
Related errors
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/1815df627e3c283f.
Report an issue: GitHub.