How Instagit Handles Connection Failures and Network Transport Errors

Instagit centralizes resilience logic in src/retry.ts to detect transport errors, apply exponential backoff, and retry failed requests up to three times before surfacing permanent failures.

Instagit is designed to remain stable during transient network problems and API hiccups. Its strategy for handling connection failures and network transport errors revolves around a single retry module that every network-facing component imports. This ensures consistent behavior whether you are registering an anonymous token or streaming a large repository analysis.

Detecting Transport Errors in Instagit

The isTransportError Utility

Before retrying, Instagit must distinguish between permanent failures and transient network blips. The isTransportError function in src/retry.ts inspects error messages for known transport-level patterns:

  • "incomplete chunked read"
  • "peer closed connection"
  • "connection reset"
  • "timed out"
  • "fetch failed"
  • "ECONNREFUSED"

If an error matches any of these strings, Instagit classifies it as a transient transport error and marks the request as eligible for retry.

Retry Policy and Backoff Strategy

Configurable Retry Limits

Instagit caps the number of retry attempts to prevent infinite loops. The MAX_RETRIES constant in src/retry.ts defaults to 3 attempts, meaning the library will execute the original request plus up to three additional tries before giving up.

Additionally, the RETRYABLE_STATUS_CODES array defines which HTTP responses indicate temporary server issues rather than client errors. Instagit retries on:

  • 303 (See Other)
  • 502 (Bad Gateway)
  • 503 (Service Unavailable)
  • 504 (Gateway Timeout)

Exponential Backoff Calculation

To avoid overwhelming the server or the network, Instagit uses exponential backoff. The getRetryDelay function calculates the wait time using the formula:


RETRY_BASE_DELAY * 2 ** attempt

This means the delay doubles with each retry attempt (e.g., 1s, 2s, 4s), giving transient connection failures and network transport errors time to resolve before the next request.

Implementing Resilience in API Calls

Token Registration with registerAnonymousToken

When acquiring an anonymous session token, Instagit must handle the initial handshake gracefully. The registerAnonymousToken function in src/token.ts wraps its HTTP call in a try-catch block that delegates to the retry logic in src/retry.ts.

If a transport error occurs during registration, the function automatically retries according to the exponential backoff policy, ensuring that a brief network hiccup does not block the entire workflow.

Streaming Analysis in analyzeRepoStreaming

The most complex retry scenario occurs in analyzeRepoStreaming within src/api.ts. This function manages Server-Sent Events (SSE) streams that can fail at any point during a long-running analysis.

The implementation wraps the entire fetch-SSE flow in a retry loop that:

  1. Retries on transport errors detected by isTransportError.
  2. Retries on retryable status codes (502, 503, 504, 303).
  3. Retries on empty response bodies received with HTTP 200, treating them as incomplete transfers up to MAX_RETRIES.
  4. Bails immediately on permanent security rejections detected by isSecurityRejection, which are never retried.

This layered approach ensures that connection failures and network transport errors during multi-minute streaming operations do not force users to restart their analysis from scratch.

Timeout and Abort Handling

Instagit prevents indefinite hangs by combining retry logic with aggressive timeout controls. Every network request uses AbortSignal.timeout(FETCH_TIMEOUT), where FETCH_TIMEOUT defaults to 30 minutes for streaming operations.

While retries are in progress, a 250-millisecond heartbeat sends progress updates via the progressCallback function. This keeps the user interface responsive and provides visibility into retry attempts, ensuring that users know the system is actively recovering from network transport errors rather than freezing.

Summary

  • Instagit detects transport errors using pattern matching in src/retry.ts to identify transient network issues like connection resets and timeouts.
  • Exponential backoff with a default of 3 retries prevents overwhelming servers while giving temporary failures time to resolve.
  • Token registration (src/token.ts) and streaming analysis (src/api.ts) both implement the centralized retry logic for consistent resilience.
  • Security rejections are treated as permanent failures and never retried, while empty HTTP 200 responses are retried as incomplete transfers.
  • 30-minute timeouts with 250-millisecond heartbeats ensure that retry loops remain responsive and never hang indefinitely.

Frequently Asked Questions

What types of network errors does Instagit detect?

Instagit detects transport-level errors by scanning error messages for patterns such as "connection reset", "timed out", "ECONNREFUSED", "fetch failed", "peer closed connection", and "incomplete chunked read". These patterns are defined in the isTransportError function within src/retry.ts.

How many times does Instagit retry a failed request?

By default, Instagit retries failed requests up to three times. This limit is controlled by the MAX_RETRIES constant in src/retry.ts. The delay between attempts uses exponential backoff, doubling with each retry to avoid overwhelming the network.

Does Instagit retry on HTTP 500 errors?

No, Instagit does not retry on HTTP 500 Internal Server Errors. The RETRYABLE_STATUS_CODES array in src/retry.ts specifically lists 303, 502, 503, and 504 as retryable. HTTP 500 is treated as a permanent server failure that requires intervention rather than automatic retry.

How does Instagit handle long-running streaming requests?

Instagit protects long-running streaming requests with a 30-minute timeout using AbortSignal.timeout(FETCH_TIMEOUT) and implements a retry loop in analyzeRepoStreaming (src/api.ts). It retries on transport errors, gateway timeouts (502/503/504), and even empty HTTP 200 responses, while sending 250-millisecond heartbeat progress updates to keep the UI responsive during recovery attempts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →