{"record":{"id":"7f698c0a1afe13e2","repo":"slopus/happy","slug":"session-not-started","errorCode":null,"errorMessage":"Session not started","messagePattern":"Session not started","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/happy-cli/src/agent/acp/AcpBackend.ts","lineNumber":1056,"sourceCode":"  private waitingForResponse = false;\n\n  async sendPrompt(sessionId: SessionId, prompt: string): Promise<void> {\n    // Check if prompt contains change_title instruction (via optional callback)\n    const promptHasChangeTitle = this.options.hasChangeTitleInstruction?.(prompt) ?? false;\n\n    // Reset tool call counter and set flag\n    this.toolCallCountSincePrompt = 0;\n    this.recentPromptHadChangeTitle = promptHasChangeTitle;\n    \n    if (promptHasChangeTitle) {\n      logger.debug('[AcpBackend] Prompt contains change_title instruction - will auto-approve first \"other\" tool call if it matches pattern');\n    }\n    if (this.disposed) {\n      throw new Error('Backend has been disposed');\n    }\n\n    if (!this.connection || !this.acpSessionId) {\n      throw new Error('Session not started');\n    }\n\n    this.emit({ type: 'status', status: 'running' });\n    this.waitingForResponse = true;\n\n    try {\n      logger.debug(`[AcpBackend] Sending prompt (length: ${prompt.length}): ${prompt.substring(0, 100)}...`);\n      logger.debug(`[AcpBackend] Full prompt: ${prompt}`);\n      \n      const contentBlock: ContentBlock = {\n        type: 'text',\n        text: prompt,\n      };\n\n      const promptRequest: PromptRequest = {\n        sessionId: this.acpSessionId,\n        prompt: [contentBlock],\n      };","sourceCodeStart":1038,"sourceCodeEnd":1074,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/agent/acp/AcpBackend.ts#L1038-L1074","documentation":"Before sending a prompt, AcpBackend verifies it holds both an ACP connection and an acpSessionId. If either is missing, no ACP session was successfully started (startSession either never ran or its handshake failed), so prompting is impossible and this error is thrown.","triggerScenarios":"Calling the prompt method before startSession() resolved; startSession's initialize/newSession handshake failed so acpSessionId was never set; the connection was reset and cleared without disposing.","commonSituations":"Agent process crashed after spawn but before session handshake; sending the first user prompt before the async session setup completes; connection loss over stdio that cleared session state.","solutions":["Await startSession() (or the backend's ready/status 'running' event) before sending prompts.","If the agent failed to start, inspect earlier status/error events and restart the backend.","Guard prompt calls with a check on the backend's session state and surface a user-visible 'agent not ready' message instead."],"exampleFix":"// before\nawait backend.sendPrompt(text);\n// after\nawait backend.startSession();\nawait backend.sendPrompt(text);","handlingStrategy":"validation","validationCode":"if (!backendReady) {\n  throw new Error('Agent session not ready; await startSession before prompting');\n}\nawait backend.sendPrompt(text);","typeGuard":null,"tryCatchPattern":"try {\n  await backend.sendPrompt(text);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Session not started') {\n    await backend.startSession();\n    await backend.sendPrompt(text);\n  } else throw err;\n}","preventionTips":["Always await startSession() completion before the first prompt.","Gate the UI's input on the backend's 'running' status event.","Handle session-start failures by restarting the backend, not retrying prompts.","Watch for agent crashes that clear session state mid-session."],"tags":["state","session","acp","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"}