Repository navigation
Description
Summary
bin/antigravity-ls-proxy.mjs's callRpc — the single method every language-server RPC goes through — calls fetch with no timeout signal. A language server that is alive enough to pass the proxy's heartbeat but wedged on real RPCs (deadlocked, stuck on its own upstream) hangs every dependent request forever: /v1/models, and every /v1/chat/completions (which blocks on GetAvailableModels before it even starts a cascade). The heartbeat in the same file pins AbortSignal.timeout(1500) (:224), and bin/sync-models.mjs's identical GetAvailableModels call pins 3000 ms — callRpc is the one unguarded path.
Evidence (main 82b019a0)
bin/antigravity-ls-proxy.mjs:372-383—callRpc(method, payload)doesawait fetch(url, { method: 'POST', headers, body })with nosignal, noAbortSignal.timeout, no deadline of any kind; callers:GetAvailableModels(:420, viagetLiveCatalog),StartCascade(:793),SendUserCascadeMessage(:806),GetCascadeTrajectorySteps(:824),GetModelResponse(:913).- Same file, :217-226 —
checkHeartbeatusessignal: AbortSignal.timeout(1500), so a wedged-but-listening server passes health checks while its RPCs hang:ensureActivesucceeds, then the request waits indefinitely. - The cascade poll loop (:822-843) has a nominal cap (120 attempts × 250 ms, then "Cascade execution timed out after 30 seconds") that a single hung
GetCascadeTrajectoryStepscallRpc defeats — the loop never advances to the next attempt. getLiveCatalog(:417-430) caches for 60 s, but a hung first pull never resolves and never caches, so every/v1/modelsand chat request piles onto the same indefinite wait.
Probe (laptop, 2026-10-28, shipped file unmodified)
Probe dir: ~/git/fleet/probe-2026-10-28-laneB-lsrpc/ (laptop) — stub language server that answers Heartbeat with 200 and never responds to any other RPC (the test file's own env attach path, ANTIGRAVITY_LS_ADDRESS/ANTIGRAVITY_CSRF_TOKEN), shipped proxy on an alternate port:
- Proxy starts and
/healthanswers (heartbeat path works against the stub). GET /v1/models: no response after 8001 ms (client-side abort fired; stub logged the hangingGetAvailableModelsRPC).POST /v1/chat/completions: no response after 8002 ms (blocked on the same hangingGetAvailableModelscallRpc, before any cascade RPC).
Why it matters
This proxy fronts a language server that is a separate, crash- and deadlock-prone process. The failure mode "process alive, RPCs wedged" is exactly the one the heartbeat cannot distinguish — and it converts a backend wedge into indefinitely hung client requests with no error, no log line, and no recovery short of restarting the proxy (which doesn't unwedge the server). Every sibling call site in the fleet already bounds this wait (heartbeat 1500 ms here; sync-models 3000 ms for the same RPC; clef-proxy 10 s, #2100; design-code-proxy dispatch, #2097).
Acceptance criteria
-
callRpccarries a bounded timeout (triage pins the value; it must comfortably exceed normalGetModelResponse/cascade-step latency — a generous per-RPC bound, not a total-request deadline), and a timed-out RPC surfaces as an error the existingcatchpaths already handle (e.g.getLiveCatalog's last-known-good fallback engages instead of hanging). - A language server that heartbeats but never answers RPCs:
/v1/modelsanswers within a bounded time (live catalog or static floor), and a chat request fails with a clean error within a bounded time — never an indefinite hang. - The cascade poll loop's 30-second cap becomes effective: a hung poll RPC counts against it instead of defeating it.
- Tests in
bin/antigravity-ls-proxy.test.mjsstyle: stub LS in heartbeat-ok/RPC-hang mode → models and chat requests resolve (value or clean error) within a bounded time; slow-but-alive LS (answers after a delay under the bound) still succeeds. - Existing behaviours unchanged: heartbeat timeout, live-catalog 60 s cache + last-known-good, model resolution (antigravity-ls-proxy: reasoning_effort 'default'/'name' resolves to a non-enum model — MODEL_MAP metadata keys pass the family lookup #686 tests), cascade and direct-RPC chat paths against a healthy stub.
Dedup
gh issue list --search "antigravity-ls-proxy timeout callRpc" and --search "antigravity": no issue covers a missing callRpc timeout. Related but distinct: #2097 (design-code-proxy backend dispatch), #2100 (clef-proxy data-path fetch), #494 (closed, LS address parsing).
Activity
developing-today commentedon Oct 29, 2026
CODE-1011
dezren39 commentedon Oct 29, 2026
🤖 Agent note · filed
11 remaining items
dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up
callRpctimeouts for issue antigravity-ls-proxy: callRpc has no timeout — a language server that heartbeats but never answers an RPC hangs /v1/models and every chat request forever #2102 inbin/antigravity-ls-proxy.mjsper the packet acceptance (method budgets, cascade elapsed deadline, bounded errors, hang/slow tests).queue/5092-2102-bound-antigravity-ls-proxy-rpcs(to be created on the laptop)dezren39 commentedon Nov 1, 2026
🤖 Agent note · done
pr_openedcallRpctimeouts (method budgets incl. body reads), strict cascade elapsed deadline, 5 new hang/slow/deadline tests —node --test bin/antigravity-ls-proxy.test.mjs18/18 PASS on the laptop.queue/5092-2102-bound-antigravity-ls-proxy-rpcsMerge pull request #4080 from developing-today/queue/5092-2102-bound-…
fix(antigravity-ls-proxy): bound each cascade poll by the remaining d…