{"record":{"id":"5bac0c9fa549d193","repo":"slopus/happy","slug":"acp-session-not-started","errorCode":null,"errorMessage":"ACP session not started","messagePattern":"ACP session not started","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/happy-cli/src/gemini/runGemini.ts","lineNumber":1050,"sourceCode":"          \n          // Start session if not started\n          if (!acpSessionId) {\n            logger.debug('[gemini] Starting ACP session...');\n            // Update permission handler with current permission mode before starting session\n            updatePermissionMode(message.mode.permissionMode);\n            const { sessionId } = await geminiBackend.startSession();\n            acpSessionId = sessionId;\n            logger.debug(`[gemini] ACP session started: ${acpSessionId}`);\n            wasSessionCreated = true;\n            currentModeHash = message.hash;\n            \n            // Model info is already shown in status bar via updateDisplayedModel\n            logger.debug(`[gemini] Displaying model in UI: ${displayedModel || 'gemini-2.5-pro'}, displayedModel: ${displayedModel}`);\n          }\n        }\n        \n        if (!acpSessionId) {\n          throw new Error('ACP session not started');\n        }\n         \n        // Reset accumulator when sending a new prompt (not when tool calls start)\n        // Reset accumulated response for new prompt\n        // This ensures a new assistant message will be created (not updating previous one)\n        accumulatedResponse = '';\n        isResponseInProgress = false;\n        hadToolCallInTurn = false;\n        taskStartedSent = false; // Reset so new turn can send task_started\n        \n        // Track if this prompt contains change_title instruction\n        // If so, don't send task_complete until change_title is completed\n        pendingChangeTitle = message.message.includes('change_title') || \n                             message.message.includes('happy__change_title');\n        changeTitleCompleted = false;\n        \n        if (!geminiBackend || !acpSessionId) {\n          throw new Error('Gemini backend or session not initialized');","sourceCodeStart":1032,"sourceCodeEnd":1068,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/gemini/runGemini.ts#L1032-L1068","documentation":"runGemini communicates with the Gemini CLI via ACP (Agent Client Protocol). A session ID is only assigned after the ACP handshake completes. When the UI update path runs and acpSessionId is still unset, the code throws rather than send a prompt against a non-existent session. This guards against sending user input before the backend is ready.","triggerScenarios":"Inside runGemini, the prompt/display flow is reached while the acpSessionId variable is still null/undefined — i.e. the ACP initialize/newSession handshake has not produced a session ID yet when a prompt arrives.","commonSituations":"User submits a prompt before the Gemini ACP process finished initializing; the gemini binary fails or is slow to start; an earlier session initialization error was swallowed so acpSessionId never gets set.","solutions":["Wait for the session-ready signal/UI indicator before typing or sending a prompt","Check the gemini CLI is installed, on PATH, and starts correctly (run `gemini --version`)","Restart the session; if it reproduces, enable debug logging to see why the ACP handshake never returned a session ID"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!acpSessionId) {\n  logger.warn('[gemini] ACP session not ready; skipping prompt');\n  return;\n}","typeGuard":"const hasAcpSession = (id: string | null | undefined): id is string => typeof id === 'string' && id.length > 0;","tryCatchPattern":"try {\n  await sendPromptToAcp(prompt);\n} catch (err) {\n  if (err instanceof Error && err.message === 'ACP session not started') {\n    await waitForSessionReady();\n    await sendPromptToAcp(prompt);\n  } else throw err;\n}","preventionTips":["Gate user input handling on the session-ready event","Log ACP handshake completion before enabling the input UI","Surface initialization failures instead of swallowing them"],"tags":["gemini","acp","session","initialization"],"backgroundTag":"session-not-initialized","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}