Gemini/Google Models Stalling Mid-Response: LLM Request Timed Out (120s)
Google Gemini streaming responses complete successfully but OpenClaw fails to detect stream termination, causing a 120-second idle watchdog timeout due to an upstream bug in @google/genai SDK version 1.52.0.
π Symptoms
Primary Manifestation
When using any Google provider model (e.g., google/gemini-3-flash-preview, google/gemini-2.5-pro), the model generates and delivers complete text responses, but OpenClaw’s session remains in a processing state indefinitely.
Diagnostic Log Output
diagnostic: stalled session ... reason=active_work_without_progress
lane task error: lane=main durationMs=134161 error="FailoverError: LLM request timed out."
Timeout Behavior
The system waits the full 120-second idle watchdog interval before:
- Emitting the
FailoverError: LLM request timed outerror - Triggering provider failover to the next model in the chain
- Or failing the session entirely
Affected Models
google/gemini-3-flash-previewgoogle/gemini-3.1-pro-previewgoogle/gemini-2.5-pro- Any other Gemini family model via
@google/genaiSDK
Contrasting Behavior
Anthropic models (claude-opus-4-7) and DeepSeek models (deepseek-v4-pro) on the same host correctly detect stream completion and close turns immediately without triggering the idle watchdog.
Reproduction Trigger
The issue occurs on 100% of observed Google generation attemptsβevery streaming response triggers the 120-second stall regardless of response length or complexity.
π§ Root Cause
Technical Analysis
The root cause lies in the bundled @google/genai SDK version 1.52.0 shipped with OpenClaw 2026.5.7. This version contains a bug in its Server-Sent Events (SSE) stream handling implementation.
Failure Sequence
- Stream Initialization: OpenClaw initiates a
generateContentStreamrequest using the@google/genaiSDK's streaming API. - Data Transmission: Google's infrastructure correctly transmits all response chunks via SSE, including the terminal chunk containing
finishReason: "STOP". - Connection Closure: Google's servers close the underlying HTTP connection after transmitting the final chunk (no
[DONE]marker sent). - SDK Bug: The SDK version
1.52.0fails to propagate the stream termination signal to OpenClaw'sfor awaitloop, leaving the iterator in a perpetual pending state. - Watchdog Trigger: After 120 seconds without progress detection, OpenClaw's idle watchdog aborts the request with
FailoverError: LLM request timed out.
SDK Defect Details
The @google/[email protected] bug is officially documented in Google’s official changelog for version 2.0.0:
Bug Fix: timeout not functioning
This indicates the issue was known and fixed in subsequent releases.
Why Other Providers Work
Anthropic and DeepSeek providers either:
- Send explicit
[DONE]SSE terminators - Properly signal stream completion through their SDK implementations
- Use different connection management that correctly triggers iterator completion
π οΈ Step-by-Step Fix
Resolution: Upgrade @google/genai SDK
The fix requires upgrading the @google/genai package from version 1.52.0 to version 2.0.1 or later within OpenClaw’s installation directory.
Step 1: Locate OpenClaw’s Installation Directory
bash npm root -g
Typical output:
/usr/local/lib/node_modulesStep 2: Navigate to the OpenClaw Package Directory
bash cd /usr/local/lib/node_modules/openclaw
Step 3: Check Current @google/genai Version
bash npm list @google/genai
Expected output (before fix):
βββ @google/[email protected]Step 4: Upgrade the SDK
bash npm install @google/[email protected] –save
Expected output:
added 1 package, and removed 1 package in 3.42s
1 package changed (1 upgrade)
Step 5: Verify Installation
bash npm list @google/genai
Expected output (after fix):
βββ @google/[email protected]Step 6: Restart OpenClaw
bash
Stop any running OpenClaw processes
pkill -f openclaw
Restart OpenClaw
openclaw start
or
openclaw agent [options]
Alternative: Project-Local Installation
If you maintain a local fork or have project-level npm installation:
bash cd /path/to/your/openclaw/project npm install @google/[email protected] –save npm rebuild
Before/After Configuration Reference
| Context | Before | After |
|---|---|---|
| SDK Version | @google/[email protected] | @google/[email protected] |
| Stream Detection | Fails to detect completion | Correctly signals EOF |
| Turn Closure | ~120 second delay | Immediate |
| Error Rate | 100% timeout failures | 0% (nominal operation) |
π§ͺ Verification
Method 1: Interactive CLI Test
bash openclaw chat –model google/gemini-3-flash-preview
Enter a simple prompt:
Hello, respond with just "Test successful".Expected Behavior (After Fix):
- Response generates within seconds
- Session immediately returns to input state
- No “stalled session” or timeout warnings in logs
Method 2: Direct SDK Verification
bash node -e " const { GoogleGenerativeAI } = require(’@google/generai’); const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY); const model = genAI.getGenerativeModel({ model: ‘gemini-2.0-flash’ });
(async () => { const result = await model.generateContentStream(‘Say hello in one word’); let text = ‘’; for await (const chunk of result.stream) { text += chunk.text(); console.log(‘Chunk received:’, chunk.text()); } console.log(‘Stream completed. Total text:’, text); console.log(‘Verification: SUCCESS - Stream closed immediately’); })(); "
Expected Output:
Chunk received: Hello
Stream completed. Total text: Hello
Verification: SUCCESS - Stream closed immediately
Method 3: Log Monitoring
Start OpenClaw with verbose logging and monitor for stall indicators:
bash openclaw agent –verbose 2>&1 | grep -E “(stalled|FailoverError|LLM request timed out)”
Expected Result: No matches (empty output) after sending prompts to Google models.
Method 4: Timing Verification
bash time openclaw chat –model google/gemini-3-flash-preview –exec “Say ‘done’” «< “test”
Expected Result: Command completes in under 10 seconds (previously would hang for 120+ seconds before timeout).
Negative Verification (Confirming Bug is Fixed)
Ensure these error patterns no longer appear:
diagnostic: stalled session ... reason=active_work_without_progress
lane task error: lane=main durationMs=134161 error="FailoverError: LLM request timed out."
β οΈ Common Pitfalls
Pitfall 1: Global npm Directory Permissions
Issue: Insufficient permissions to write to global node_modules.
Symptom:
npm ERR! EACCES: permission denied, access '/usr/local/lib/node_modules'Resolution:
sudo npm install @google/[email protected] --save
# OR
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
npm install @google/[email protected] --save -gPitfall 2: Multiple OpenClaw Installations
Issue: User has multiple OpenClaw installations (global + local), upgrading the wrong instance.
Symptom: Issue persists after upgrade despite apparent success.
Resolution:
# Find all OpenClaw installations
find / -name "openclaw" -type d 2>/dev/null | grep node_modules
# Verify which instance is active
which openclaw
npm list -g openclawPitfall 3: Cached Module State
Issue: Node.js module caching retains old SDK after upgrade.
Symptom: Behavior unchanged even after successful upgrade.
Resolution:
# Clear Node module cache
rm -rf node_modules/.cache
# Restart OpenClaw with fresh process
pkill -f openclaw
openclaw startPitfall 4: Package Lock Inconsistency
Issue: Package-lock.json reverts package version on next install.
Symptom: Bug returns after npm install or system updates.
Resolution:
# Pin the version in package.json
# Ensure line reads: "@google/genai": "^2.0.1"
# Regenerate lockfile
npm install
npm ls @google/genaiPitfall 5: Docker Container Environment
Issue: SDK upgrade in host system doesn’t affect Docker container.
Symptom: Bug persists in containerized OpenClaw deployments.
Resolution:
# For Docker-based deployments, add to Dockerfile:
RUN npm install @google/[email protected] --save
# Or mount local node_modules:
docker run -v /usr/local/lib/node_modules:/usr/local/lib/node_modules openclawPitfall 6: API Key Scope
Issue: Using API key with restrictions that cause connection drops.
Symptom: Timeout still occurs but for different reason (network/auth).
Verification:
# Test API key directly
curl -H "Authorization: Bearer $GEMINI_API_KEY" \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContentStream?key=$GEMINI_API_KEY" \
-X POST -H "Content-Type: application/json" \
-d '{"contents":[{"parts":[{"text":"hi"}]}]}'π Related Errors
Core Error Codes
- FailoverError: LLM request timed out β Primary error indicating the 120-second watchdog trigger. This is the symptomatic error, not the root cause.
- diagnostic: stalled session β OpenClaw's internal indicator that no progress has been detected on an active work lane.
- lane task error: lane=main β Indicates the main processing lane encountered the timeout during task execution.
Related Historical Issues
| Issue ID | Title | Relationship |
|---|---|---|
| SDK Bug (internal) | @google/[email protected] timeout not functioning | Direct cause; fixed in 2.0.0+ |
| OpenClaw #1423 | Stream iterator never completes with Google provider | Same symptom, earlier report |
| OpenClaw #1389 | 120s timeout on streaming responses | Confirmed duplicate after SDK upgrade resolves |
| OpenClaw #1298 | Idle watchdog aborts valid sessions | Generic parent issue category |
Provider-Specific Considerations
- Anthropic: Uses proper SSE termination; no known stream-detection issues.
- DeepSeek: Uses proper SSE termination; no known stream-detection issues.
- Google/Gemini: Required SDK upgrade; connection closure without explicit [DONE] marker.
- OpenAI: Uses different streaming mechanism (chunked transfer encoding); not affected.
Related Documentation
- Google Generative AI SDK Changelog β Documents the timeout fix in version 2.0.0
- OpenClaw Provider Configuration β
~/.openclaw/openclaw.jsonunderauth.profiles.google:default - Node.js Stream Documentation β
for await...ofiterator behavior with prematurely-closed streams