Yeachan-Heo/oh-my-codex · error · Error
mutation_not_allowed
mutation_not_allowed
Error message
mutating Hermes bridge tools require allow_mutation: true
What it means
Hermes bridge tools that mutate state (submit answers, send prompts, start sessions, report status) refuse to run unless the caller explicitly passes allow_mutation: true. This is a safety interlock so MCP clients cannot accidentally trigger side effects.
Source
Thrown at src/mcp/hermes-bridge.ts:147
error: string,
): HermesBridgeResult<T> {
return { ok: false, code, error };
}
function normalizeString(value: unknown, name: string, options: { required?: boolean } = {}): string | undefined {
if (value == null) {
if (options.required) throw new Error(`${name} is required`);
return undefined;
}
if (typeof value !== "string") throw new Error(`${name} must be a string`);
const trimmed = value.trim();
if (!trimmed && options.required) throw new Error(`${name} must be non-empty`);
return trimmed || undefined;
}
function requireMutation(args: Record<string, unknown>): void {
if (args.allow_mutation !== true) {
throw new Error("mutating Hermes bridge tools require allow_mutation: true");
}
}
function normalizePositiveInteger(value: unknown, fallback: number, max: number): number {
if (value == null) return fallback;
const parsed = typeof value === "number" ? value : Number.parseInt(String(value), 10);
if (!Number.isInteger(parsed) || parsed <= 0) return fallback;
return Math.min(parsed, max);
}
async function readJsonFile<T>(path: string): Promise<T | null> {
try {
return safeJsonParse<T | null>(await readFile(path, "utf-8"), null);
} catch {
return null;
}
}
View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Add allow_mutation: true to the tool arguments
- Only do so for trusted, intentional mutations
- Keep read-only tools (like hermesListQuestions) without the flag
Example fix
// before
hermesSendPrompt({ session_id: "s1", prompt: "go" })
// after
hermesSendPrompt({ session_id: "s1", prompt: "go", allow_mutation: true }) Defensive patterns
Strategy: validation
Validate before calling
if (toolMutates) args.allow_mutation = true; // set before calling
Try / catch
catch (e) { if ((e as Error).message.includes('allow_mutation')) { if (userConfirmedIntent) { retry with allow_mutation: true } } } Prevention
- Treat allow_mutation as an explicit user consent step
- Gate mutating calls behind UI confirmation
- Keep read-only calls free of the flag
When it happens
Trigger: Calling hermesSubmitQuestionAnswer, hermesSendPrompt, hermesStartSession, or hermesReportStatus without allow_mutation: true in the args object.
Common situations: New client integration omitting the safety flag, or a cautious default in generated client code that strips unknown fields.
Related errors
- ${name} is required
- ${name} must be a string
- ${name} must be non-empty
- unsupported_session_kind
- tmux_instance_mismatch
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/712306927b8ec5bc.
Report an issue: GitHub.