PAL-BUG-2: `pal__analyze` intermittently returns `empty_response` after long body-read

Author: primovera12Created May 25, 2026Updated May 25, 2026

Reporter: [email protected] (via /eval-models routing review) First observed: 2026-W22 (2026-05-25, ~03:24Z) Repro attempt: 2026-W23 (2026-05-25, ~18:38Z) — did NOT reproduce; intermittent Repo: BeehiveInnovations/pal-mcp-server @ branch main Severity: medium (workaround exists; intermittent symptom)

TL;DR

pal__analyze called with model=google/gemini-2.5-pro and a small (~6K tokens) attached file returned {"error":"No response from model","status":"empty_response"} after a 3-minute-42-second body read. OpenRouter's /v1/generation/{id} API confirmed the request reached the provider (a gen-id was minted) but all metadata fields (tokens, cost, finish_reason) were null.

On the W23 repro attempt with effectively the same prompt + fixture, the call succeeded with full output and normal metadata. The bug is intermittent.

W22 Evidence (the failing case)

Tool invocation (paraphrased — Master Claude with frozen test-prompts.md path):

pal__analyze(
  step="Analyze the attached TypeScript codebase slice. Identify: (1) top 3 architectural risks, (2) 5 buggy files, (3) cross-file inconsistencies. Cite file:line for every finding.",
  step_number=1, total_steps=1, next_step_required=False,
  findings="Initial pass — long-context analysis.",
  relevant_files=["/home/rabih/.claude/openrouter-models/test-fixtures/longcontext-50k.txt"],
  model="google/gemini-2.5-pro",
  analysis_type="architecture",
  confidence="medium",
)

Response from pal__analyze:

json
{"error":"No response from model","status":"empty_response"}

Wall-clock latency: ~225 seconds before PAL gave up.

PAL log evidence (paraphrased): HTTP 200 received from OpenRouter, X-Generation-Id gen-1779687428-ty4eM7grau9sQ29iYsy1, response body started arriving but never completed — PAL's content parser saw empty content.

OpenRouter API check on the gen-id:

bash
curl -H "Authorization: Bearer $KEY" https://openrouter.ai/api/v1/generation?id=gen-1779687428-ty4eM7grau9sQ29iYsy1 | jq .data
{
  "model": null,
  "tokens_prompt": null,
  "tokens_completion": null,
  "total_cost": null,
  "generation_time": null,
  "finish_reason": null,
  "native_finish_reason": null,
  "error": null
}

OpenRouter has the request record but no completion fields — consistent with a stalled stream that never reached a stop frame.

W23 repro attempt (the passing case)

Same tool, same model, same fixture (longcontext-50k.txt), nearly-same prompt. Response: full ~4500-token analysis with provider_used: openrouter, finish_reason: stop, total_cost: 0.04276, generation_time: 36799 ms. Gen-id gen-1779734315-ZNiWkW13ptH95KTDwyUF.

The W22 vs W23 prompt differed only in trailing whitespace + a one-line summary directive — not enough to explain the symptom delta.

Hypothesis

Three candidate causes (not exhaustive):

  1. Provider-side stream stall on Gemini 2.5 Pro via OpenRouter. Some downstream node times out the stream after a long thinking burst but doesn't emit the final SSE done frame. PAL's parser, expecting a complete stream, ends with empty content.
  2. pal__analyze tool's wrapper system-prompt triggers Gemini thinking-token exhaustion. The analyze tool prepends an elaborate "expert analysis" system prompt; combined with thinking budget, output budget could starve to zero.
  3. PAL's body-read timeout interacts badly with Gemini streaming via OpenRouter. PAL may have a httpx timeout that lets the connection idle long enough to half-close.

The chat-reroute workaround (route the same prompt via pal__chat) consistently works — suggesting the analyze tool's wrapper, not the underlying model, is in the failure path. But the W23 success makes it harder to nail down a specific config knob.

Workaround in use today

Re-route analyze prompts via pal__chat with the same model + the analyze system-prompt-modifier prepended to the user prompt. This bypasses pal__analyze's expert-validation wrapper.

Asks for upstream

  1. Add a server-side timeout-and-retry around the analyze tool's expert-validation HTTP call. If the response body has been idle for >60s with no content, abort and retry once.
  2. Surface the gen-id in the error response. Currently {"error":"No response from model","status":"empty_response"} gives nothing diagnostic. Including the gen-id would let callers correlate against OpenRouter logs without scraping mcp_server.log.
  3. Investigate Gemini 2.5 Pro stream-stall pattern via OpenRouter. Check whether OpenRouter has known incidents around the affected timestamp (2026-05-25T03:24:00Z approx).

Cross-references

  • W22 routing review: ~/.claude/openrouter-models/results/2026-W22.md F2 + Failures section
  • W23 routing review: ~/.claude/openrouter-models/results/2026-W23.md Section B (PAL-BUG-2)
  • Failing gen-id: gen-1779687428-ty4eM7grau9sQ29iYsy1 (epoch 1779687428 = 2026-05-25T03:23:48Z)
  • Passing gen-id: gen-1779734315-ZNiWkW13ptH95KTDwyUF (epoch 1779734315 = 2026-05-25T15:38:35Z)

Source: BeehiveInnovations/pal-mcp-server