Skip to content

Fix WebSocket disconnects with Home Assistant 2026.10 (bump Starscream and HAKit) - #6038

Merged
bgoncal merged 3 commits into
mainfrom
fix-websocket-control-frame-compression
Oct 10, 2026
Merged

bgoncal merged 3 commits into
mainfrom
fix-websocket-control-frame-compression

Conversation

@bgoncal

@bgoncal bgoncal commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

AI Policy

Select exactly one option that describes AI usage in this contribution:

  • I have not used AI for this contribution.
  • AI assistance was used for this contribution.
  • AI fully generated the code for this contribution, but I've reviewed and understood it before submitting and will respond without AI during review.

Summary

Fixes #6011 (also reported as #5999 and home-assistant/core#184799).

Since Core 2026.10.0 the app's WebSocket is dropped roughly every 56 seconds with Received frame with non-zero reserved bits (close code 1002).

Root cause: Starscream ran every outgoing frame through the permessage-deflate compressor, so control frames (close/ping/pong) went out with RSV1 set — including the empty pong it sends back for the server's 55 s heartbeat ping. RFC 7692 §6.1 forbids that; aiohttp 3.14.4 (bumped in home-assistant/core#184382) now enforces it, while 3.14.3 tolerated it.

Not affected before this change: watchOS (compression already disabled in HAKit) and mTLS connections (URLSessionWebSocketTask).

Screenshots

N/A

Link to pull request in Documentation repository

Documentation: home-assistant/companion.home-assistant#

Any other notes

Reproduced against aiohttp directly with a raw client sending Starscream's frame bytes: pong 0xCA (FIN|RSV1) is rejected by 3.14.4 with the exact error above and accepted by 3.14.3; a compliant 0x8A pong is accepted by both.

The app requires iOS 16.4, so iOS 15 devices on older app builds will keep hitting this against Core 2026.10+ — a server-side tolerance would need to come from aiohttp/Core.

Starscream set the permessage-deflate compressed bit on control frames,
including the pong answering the server's heartbeat ping. aiohttp 3.14.4
(Home Assistant Core 2026.10) rejects those per RFC 7692, dropping the
connection with "Received frame with non-zero reserved bits" roughly
every 56 seconds.

Refs #6011

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017NccCmJppSCweVhhGQn8Hk
HAKit 0.4.19 requires Starscream 4.0.10, the release carrying the
control-frame compression fix this PR already pins.

Refs #6011

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017NccCmJppSCweVhhGQn8Hk
@bgoncal
bgoncal marked this pull request as ready for review October 10, 2026 21:08
Copilot AI balanced review requested due to automatic review settings October 10, 2026 21:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Two local package manifests still require HAKit 0.4.18 exactly, creating an unsatisfiable SwiftPM graph.

1 open finding
What changed in this PR

Updates WebSocket dependencies to fix protocol-error disconnects with Home Assistant 2026.10.

Changes:

  • Bumps HAKit to 0.4.19.
  • Pins Starscream 4.0.10’s control-frame compression fix.
File Description
Package.resolved Updates resolved dependency revisions.
HomeAssistant.xcodeproj/​project.xcworkspace/​xcshareddata/​swiftpm/​Package.resolved Updates workspace dependency resolutions.
HomeAssistant.xcodeproj/​project.pbxproj Updates project-level package requirements.

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread HomeAssistant.xcodeproj/project.pbxproj
HANetworking and PromiseKitDynamic pin HAKit exactly to keep a single
instance in Xcode's package graph, so they must match the app's 0.4.19.

Refs #6011

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017NccCmJppSCweVhhGQn8Hk
@bgoncal
bgoncal enabled auto-merge (squash) October 10, 2026 21:32
@codecov

codecov Bot commented Oct 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 54.17%. Comparing base (9ecc20c) to head (a9bc471).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6038   +/-   ##
=======================================
  Coverage   54.16%   54.17%           
=======================================
  Files        1244     1244           
  Lines       82644    82644           
=======================================
+ Hits        44766    44772    +6     
+ Misses      37878    37872    -6     

see 7 files with indirect coverage changes

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bgoncal
bgoncal merged commit f0e314f into main Oct 10, 2026
15 checks passed
@bgoncal
bgoncal deleted the fix-websocket-control-frame-compression branch October 10, 2026 22:12
jaipur2001 added a commit to jaipur2001/homeassistant-iOS that referenced this pull request Oct 12, 2026
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.

WebSocket disconnect: "Received frame with non-zero reserved bits" after upgrading to Home Assistant 2026.10

3 participants