slopus/happy · error · Error
Session not started
Error message
Session not started
What it means
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.
Source
Thrown at packages/happy-cli/src/agent/acp/AcpBackend.ts:1056
private waitingForResponse = false;
async sendPrompt(sessionId: SessionId, prompt: string): Promise<void> {
// Check if prompt contains change_title instruction (via optional callback)
const promptHasChangeTitle = this.options.hasChangeTitleInstruction?.(prompt) ?? false;
// Reset tool call counter and set flag
this.toolCallCountSincePrompt = 0;
this.recentPromptHadChangeTitle = promptHasChangeTitle;
if (promptHasChangeTitle) {
logger.debug('[AcpBackend] Prompt contains change_title instruction - will auto-approve first "other" tool call if it matches pattern');
}
if (this.disposed) {
throw new Error('Backend has been disposed');
}
if (!this.connection || !this.acpSessionId) {
throw new Error('Session not started');
}
this.emit({ type: 'status', status: 'running' });
this.waitingForResponse = true;
try {
logger.debug(`[AcpBackend] Sending prompt (length: ${prompt.length}): ${prompt.substring(0, 100)}...`);
logger.debug(`[AcpBackend] Full prompt: ${prompt}`);
const contentBlock: ContentBlock = {
type: 'text',
text: prompt,
};
const promptRequest: PromptRequest = {
sessionId: this.acpSessionId,
prompt: [contentBlock],
};View on GitHub (pinned to b824cd0a46)
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.
Example fix
// before await backend.sendPrompt(text); // after await backend.startSession(); await backend.sendPrompt(text);
Defensive patterns
Strategy: validation
Validate before calling
if (!backendReady) {
throw new Error('Agent session not ready; await startSession before prompting');
}
await backend.sendPrompt(text); Try / catch
try {
await backend.sendPrompt(text);
} catch (err) {
if (err instanceof Error && err.message === 'Session not started') {
await backend.startSession();
await backend.sendPrompt(text);
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ACP session is not started
- ACP session not started
- Backend has been disposed
- Gemini backend or session not initialized
- Failed to create stdio pipes
AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31).
Data as JSON: /api/errors/7f698c0a1afe13e2.
Report an issue: GitHub.