Skip to content

[Bug P2] Tick timeout closes WebSocket without flushing pending requests #45468

@chrislro

Description

@chrislro

Summary

When startTickWatch() detects a tick timeout (gap > tickIntervalMs * 2), it closes the WebSocket but does not flush/reject the pending requests in this.pending. Those requests then hang indefinitely until flushPendingErrors is eventually called.

Root Cause

// startTickWatch(), src/gateway/client.ts
if (gap > this.tickIntervalMs * 2) {
  this.ws?.close(4000, "tick timeout");
  // pending requests are NOT flushed here
}

flushPendingErrors is called on the close event, but there is a window between the close call and the event firing where new pending entries could accumulate or existing ones remain.

Impact

  • Pending requests may not be rejected promptly on tick timeout
  • Combined with Bug P1 (no request timeout), this creates a compounding leak
  • Adds latency to error propagation during gateway disconnects

Suggested Fix

if (gap > this.tickIntervalMs * 2) {
  this.flushPendingErrors(new Error("Tick timeout — gateway unresponsive"));
  this.ws?.close(4000, "tick timeout");
}

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions