{"record":{"id":"2e79d96466f54e4f","repo":"google-gemini/gemini-cli","slug":"invalid-or-unavailable-mode-modeid","errorCode":null,"errorMessage":"Invalid or unavailable mode: ${modeId}","messagePattern":"Invalid or unavailable mode: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/acp/acpSession.ts","lineNumber":213,"sourceCode":"    this.disposeController.abort();\n  }\n\n  async cancelPendingPrompt(): Promise<void> {\n    if (!this.pendingPrompt) {\n      throw new Error('Not currently generating');\n    }\n\n    this.pendingPrompt.abort();\n    this.pendingPrompt = null;\n  }\n\n  setMode(modeId: acp.SessionModeId): acp.SetSessionModeResponse {\n    const availableModes = buildAvailableModes(\n      this.context.config.isPlanEnabled(),\n    );\n    const mode = availableModes.find((m) => m.id === modeId);\n    if (!mode) {\n      throw new Error(`Invalid or unavailable mode: ${modeId}`);\n    }\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion\n    this.context.config.setApprovalMode(mode.id as ApprovalMode);\n    return {};\n  }\n\n  private getAvailableCommands() {\n    return this.commandHandler.getAvailableCommands();\n  }\n\n  async sendAvailableCommands(): Promise<void> {\n    const availableCommands = this.getAvailableCommands().map((command) => ({\n      name: command.name,\n      description: command.description,\n    }));\n\n    await this.sendUpdate({\n      sessionUpdate: 'available_commands_update',","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/cli/src/acp/acpSession.ts#L195-L231","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","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."],"exampleFix":"// before\nsession.setMode('plan' as acp.SessionModeId); // throws if plan disabled\n\n// after\nconst modes = buildAvailableModes(config.isPlanEnabled());\nif (modes.some((m) => m.id === targetModeId)) {\n  session.setMode(targetModeId);\n} else {\n  // handle unavailable mode\n}","handlingStrategy":"validation","validationCode":"import { buildAvailableModes } from './acpUtils.js';\n\nfunction isModeAvailable(modeId: string, isPlanEnabled: boolean): boolean {\n  return buildAvailableModes(isPlanEnabled).some((m) => m.id === modeId);\n}\n\n// Before calling setMode:\nif (!isModeAvailable(targetModeId, config.isPlanEnabled())) {\n  throw new Error(`Mode ${targetModeId} is not available in this configuration.`);\n}\nsession.setMode(targetModeId as acp.SessionModeId);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["acp","session","mode","configuration"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}