slopus/happy · error

Gemini backend or session not initialized

Error message

Gemini backend or session not initialized

What it means

Before sending a queued message (task_complete flow), runGemini re-validates that the Gemini backend object and the ACP session ID both exist. If either is missing the message cannot be forwarded to the agent, so it throws. This typically means the backend was never started or already shut down when a queued message was processed.

Source

Thrown at packages/happy-cli/src/gemini/runGemini.ts:1068

          throw new Error('ACP session not started');
        }
         
        // Reset accumulator when sending a new prompt (not when tool calls start)
        // Reset accumulated response for new prompt
        // This ensures a new assistant message will be created (not updating previous one)
        accumulatedResponse = '';
        isResponseInProgress = false;
        hadToolCallInTurn = false;
        taskStartedSent = false; // Reset so new turn can send task_started
        
        // Track if this prompt contains change_title instruction
        // If so, don't send task_complete until change_title is completed
        pendingChangeTitle = message.message.includes('change_title') || 
                             message.message.includes('happy__change_title');
        changeTitleCompleted = false;
        
        if (!geminiBackend || !acpSessionId) {
          throw new Error('Gemini backend or session not initialized');
        }
        
        // The prompt already includes system prompt and change_title instruction (added in onUserMessage handler)
        // This is done in the message queue, so message.message already contains everything
        let promptToSend = message.message;
        
        // Inject conversation history context if model was just changed
        if (injectHistoryContext && conversationHistory.hasHistory()) {
          const historyContext = conversationHistory.getContextForNewSession();
          promptToSend = historyContext + promptToSend;
          logger.debug(`[gemini] Injected conversation history context (${historyContext.length} chars)`);
          // Don't clear history - keep accumulating for future model changes
        }
        
        logger.debug(`[gemini] Sending prompt to Gemini (length: ${promptToSend.length}): ${promptToSend.substring(0, 100)}...`);
        logger.debug(`[gemini] Full prompt: ${promptToSend}`);
        
        // Retry logic for transient Gemini API errors (empty response, internal errors)

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Ensure the Gemini backend/session is fully initialized before any message is queued
  2. Guard the queue drain so it stops when the backend is disposed, and clear pending messages on backend exit
  3. Check logs for an earlier crash of the gemini ACP process that left geminiBackend/acpSessionId stale

Example fix

// before
await sendMessage(message.message);
// after
if (!geminiBackend || !acpSessionId) {
  logger.warn('[gemini] Skipping message: backend already shut down');
  return;
}
await sendMessage(message.message);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!geminiBackend || !acpSessionId) {
  logger.warn('[gemini] backend/session gone; dropping queued message');
  return;
}

Type guard

const backendReady = (b: GeminiBackend | null, s: string | null): b is GeminiBackend =>
  b !== null && typeof s === 'string' && s.length > 0;

Try / catch

try {
  await queue.drain();
} catch (err) {
  if (err instanceof Error && err.message.includes('not initialized')) {
    queue.clear(); // backend shut down; drop pending messages
  } else throw err;
}

Prevention

When it happens

Trigger: The message queue processes a message containing 'change_title'/'happy__change_title' while geminiBackend is null (never initialized or disposed) or acpSessionId is unset.

Common situations: Race where the Gemini process exits mid-run and a queued message (e.g. automatic title change) is still processed; calling the task-complete path before runGemini finished initialization; backend cleanup on shutdown firing before the queue drains.

Related errors


AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31). Data as JSON: /api/errors/dcc8bf654f3d3100. Report an issue: GitHub.