google-gemini/gemini-cli

bug: TUI hangs indefinitely on "Initializing..." — IdeClient.getInstance() blocks BuiltinCommandLoader in bare terminal

Open

#21477 opened on Mar 6, 2026

View on GitHub
 (11 comments) (0 reactions) (1 assignee)TypeScript (103,992 stars) (13,657 forks)batch import
area/coreeffort/largehelp wantedkind/bugpriority/p1status/bot-triagedstatus/need-retestingstatus/possible-duplicatetype/bug

Description

Description

Gemini CLI v0.32.1 interactive TUI hangs forever on the "Initializing..." spinner when launched from a bare Linux terminal (not inside any IDE). Headless mode (gemini -p "hello") works perfectly.

Root Cause (Diagnosed)

The hang originates in BuiltinCommandLoader.loadCommands() which awaits ideCommand(). This calls IdeClient.getInstance()getIdeProcessInfo()getProcessInfo(pid) which runs ps -o ppid=,command= -p <pid> in a loop, traversing up the process tree looking for a parent IDE.

On certain Linux systems running from a bare terminal, this process traversal never completes — the execAsync('ps ...') call hangs on a specific PID in the ancestor chain.

Because BuiltinCommandLoader never resolves, Promise.allSettled() in CommandService.create() never settles, slashCommands is never set, and the TUI condition (!uiState.slashCommands || !uiState.isConfigInitialized) keeps rendering ConfigInitDisplay ("Initializing...") forever.

Evidence from instrumentation

Added fs.appendFileSync logging to each loader in CommandService.create():

[CMD] loader[0] McpPromptLoader DONE
[CMD] loader[2] FileCommandLoader DONE
# loader[1] BuiltinCommandLoader — NEVER completes

[BUILTIN] isNightly DONE: false
[BUILTIN] ideCommand START
# ideCommand — NEVER completes

config.initialize() completes in ~120ms. The issue is exclusively in the slash command loading phase.

Suggested Fix

Add a timeout to ideCommand() in BuiltinCommandLoader.loadCommands(), or make getIdeProcessInfo() non-blocking with an AbortSignal / timeout. When running from a bare terminal (no IDE detected within N seconds), it should fall back gracefully instead of blocking startup indefinitely.

Example:

// Instead of:
await ideCommand(),

// Use:
await Promise.race([
  ideCommand(),
  new Promise(resolve => setTimeout(() => resolve(noIdeFallbackCommand), 5000))
]),

Workaround

Replace await ideCommand(), in BuiltinCommandLoader.js with a static no-IDE object:

GEMINI_PATH=$(dirname $(readlink -f $(which gemini)))/../lib/node_modules/@google/gemini-cli
sed -i "s|await ideCommand(),|{ name: 'ide', description: 'Manage IDE integration (disabled)', kind: 'built-in', autoExecute: false, action: () => ({ type: 'message', messageType: 'info', content: 'IDE integration is not available.' }) },|" \
  "$GEMINI_PATH/dist/src/services/BuiltinCommandLoader.js"

Environment

  • OS: Ubuntu 24.04+ (Linux 6.17.0-14-generic, x86_64)
  • Gemini CLI: v0.32.1
  • Node.js: v24.14.0
  • Terminal: GNOME Terminal / bare terminal (NOT inside VS Code, Cursor, or any IDE)
  • Shell: bash

Steps to Reproduce

  1. Install Gemini CLI on Ubuntu Linux: npm install -g @google/gemini-cli
  2. Authenticate: gemini -p "hello" (works fine in headless)
  3. Launch interactive TUI from a bare terminal: gemini
  4. Observe: TUI shows logo, briefly flashes "Waiting for auth...", then stays on "Initializing..." forever
  5. Confirm headless works: gemini -p "hello" responds normally

Related Issues

  • #13986 (TUI stuck at Initializing — attributed to MCP, but may also be this bug)
  • #20433 (Initializing hang due to ripgrep — different root cause, same symptom)

Contributor guide