Skip to content

fix: report actual HTTP status codes in connectWs instead of generic connection error#1075

Open
codicerecta wants to merge 2 commits intolivekit:mainfrom
codicerecta:fix/connectws-error-reporting
Open

fix: report actual HTTP status codes in connectWs instead of generic connection error#1075
codicerecta wants to merge 2 commits intolivekit:mainfrom
codicerecta:fix/connectws-error-reporting

Conversation

@codicerecta
Copy link

Description

The connectWs function misreports all HTTP errors (rate limits, auth failures, server errors) as a generic APIConnectionError with the message "Error connecting to LiveKit WebSocket". This makes it impossible to diagnose issues like 429 rate limiting, 401 auth
failures, or 500 server errors.

Root cause: The ws library doesn't set err.code to the HTTP status code on failed WebSocket upgrades — it only includes the status in the error message string (e.g., "Unexpected server response: 429"). The existing err.code === 429 check never matched.

Fix: Register a ws unexpected-response event handler that receives the actual http.IncomingMessage with res.statusCode before the generic error event fires. This is the documented ws mechanism for handling non-101 HTTP responses.

Changes Made

  • Add unexpected-response handler that rejects with APIStatusError carrying the real HTTP status code
  • 429 responses get a specific "LiveKit gateway quota exceeded" message with retryable: true (overriding the APIStatusError default of retryable: false for 4xx)
  • Other HTTP errors (401, 500, etc.) reject with APIStatusError and the actual status code
  • Simplify onError to only handle real network errors (DNS, TLS, ECONNREFUSED) and preserve the original error message instead of discarding it
  • Narrow the import from ../index.js to ../_exceptions.js

Pre-Review Checklist

  • Build passes: All builds (lint, typecheck, tests) pass locally
  • AI-generated code reviewed: Removed unnecessary comments and ensured code quality
  • Changes explained: All changes are properly documented and justified above
  • Scope appropriate: All changes relate to the PR title, or explanations provided for why they're included
  • Video demo: N/A — this is an error handling fix in internal connection logic, not a UI change

Testing

  • Automated tests added/updated (if applicable)
  • All tests pass
  • Make sure both restaurant_agent.ts and realtime_agent.ts work properly (for major changes)

New test file agents/src/inference/utils.test.ts covers:

  • 429 → APIStatusError with statusCode: 429, retryable: true
  • 401 → APIStatusError with statusCode: 401, retryable: false
  • 500 → APIStatusError with statusCode: 500, retryable: true
  • Network error (ECONNREFUSED) → APIConnectionError with original message preserved
  • Timeout → APIConnectionError with timeout message

Tests use real HTTP servers bound to 127.0.0.1:0 rather than mocking, exercising actual ws library behavior.

Additional Notes

Before this fix, a 429 rate limit from the LiveKit inference gateway produced this unhelpful error:
APIConnectionError: Error connecting to LiveKit WebSocket

After this fix:
APIStatusError: LiveKit gateway quota exceeded (statusCode=429, retryable=true)


Note to reviewers: Please ensure the pre-review checklist is completed before starting your review.

…connection error

The ws library doesn't set err.code to the HTTP status code on failed
WebSocket upgrades — it only includes the status in the error message
string. This meant the existing err.code === 429 check never matched,
and all HTTP errors (rate limits, auth failures, server errors) were
misreported as a generic APIConnectionError with "Error connecting to
LiveKit WebSocket".

Fix: register an 'unexpected-response' handler on the WebSocket, which
receives the actual http.IncomingMessage with res.statusCode before the
generic error event fires. HTTP errors now reject with APIStatusError
carrying the real status code. The onError handler is simplified to only
handle network errors (DNS, TLS, ECONNREFUSED) and preserves the
original error message instead of discarding it.

Also narrows the import from '../index.js' to '../_exceptions.js' and
adds tests covering 429, 401, 500, network errors, and timeouts.
@changeset-bot
Copy link

changeset-bot bot commented Feb 25, 2026

🦋 Changeset detected

Latest commit: 14bdd85

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 21 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hedra Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-xai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant
Copy link

CLAassistant commented Feb 25, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

@toubatbrian
Copy link
Contributor

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@toubatbrian
Copy link
Contributor

LG! Can you fix the linting error?

@toubatbrian
Copy link
Contributor

cc @codicerecta

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants