google-gemini/gemini-cli · error
Invalid or unavailable mode: ${modeId}
Error message
Invalid or unavailable mode: ${modeId} What it means
setMode() looks up the requested mode ID in the list returned by buildAvailableModes(). The always-available modes are 'default', 'auto_edit', and 'yolo' (mapped from ApprovalMode enum values). The 'plan' mode is only included when config.isPlanEnabled() returns true. An unrecognized or currently-unavailable mode ID triggers this error.
Source
Thrown at packages/cli/src/acp/acpSession.ts:213
this.disposeController.abort();
}
async cancelPendingPrompt(): Promise<void> {
if (!this.pendingPrompt) {
throw new Error('Not currently generating');
}
this.pendingPrompt.abort();
this.pendingPrompt = null;
}
setMode(modeId: acp.SessionModeId): acp.SetSessionModeResponse {
const availableModes = buildAvailableModes(
this.context.config.isPlanEnabled(),
);
const mode = availableModes.find((m) => m.id === modeId);
if (!mode) {
throw new Error(`Invalid or unavailable mode: ${modeId}`);
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
this.context.config.setApprovalMode(mode.id as ApprovalMode);
return {};
}
private getAvailableCommands() {
return this.commandHandler.getAvailableCommands();
}
async sendAvailableCommands(): Promise<void> {
const availableCommands = this.getAvailableCommands().map((command) => ({
name: command.name,
description: command.description,
}));
await this.sendUpdate({
sessionUpdate: 'available_commands_update',View on GitHub (pinned to 5024443c72)
Solutions
- Use the availableModes list from the session initialize response and only send IDs found there.
- If requesting plan mode, ensure plan is enabled in the server-side configuration (config.isPlanEnabled()).
- Check isPlanEnabled() on the config before attempting to set plan mode.
Example fix
// before
session.setMode('plan' as acp.SessionModeId); // throws if plan disabled
// after
const modes = buildAvailableModes(config.isPlanEnabled());
if (modes.some((m) => m.id === targetModeId)) {
session.setMode(targetModeId);
} else {
// handle unavailable mode
} Defensive patterns
Strategy: validation
Validate before calling
import { buildAvailableModes } from './acpUtils.js';
function isModeAvailable(modeId: string, isPlanEnabled: boolean): boolean {
return buildAvailableModes(isPlanEnabled).some((m) => m.id === modeId);
}
// Before calling setMode:
if (!isModeAvailable(targetModeId, config.isPlanEnabled())) {
throw new Error(`Mode ${targetModeId} is not available in this configuration.`);
}
session.setMode(targetModeId as acp.SessionModeId); Prevention
- Use the availableModes list from the session initialize response as the source of truth for valid mode IDs.
- Check config.isPlanEnabled() before requesting plan mode.
- Handle version skew gracefully — a mode available in a newer server may not exist in an older one.
When it happens
Trigger: Passing a modeId not in the available list — e.g., 'plan' when plan mode is disabled in config, or any unknown string. The available modes are advertised in the session initialize response via buildAvailableModes().
Common situations: Client sends 'plan' mode without plan being enabled in the server config; version mismatch between client and server mode lists; client using a mode ID from a newer or older protocol version.
Related errors
- Not currently generating
- Command requires a workspace.
- Extension validation failed.
- The --session-id option cannot be empty.
- Invalid session ID "${trimmed}": Only alphanumeric character
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/2e79d96466f54e4f.
Report an issue: GitHub.