From 47caf34c8de2284ffc5e3181996f6adf32e399b8 Mon Sep 17 00:00:00 2001 From: Chris Grocki Date: Fri, 19 Jun 2026 22:14:23 -0400 Subject: [PATCH] fix: avoid node-fetch@2 gzip "Premature close" crash loop on Node 24 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Node 18+ (notably Node 24), node-fetch@2's gzip decode throws "Premature close" on Leviton's responses. The error is async and uncaught, becomes an uncaughtException, and Homebridge self-SIGTERMs on it — crash-looping the whole bridge under hb-service. Defaulting compress:false skips the failing gzip path; verified 4/4 200 OK on Node 24 where gzip failed 4/4. Fixes #52. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01PJbj8QvW5GdZbcDAXgqMHV --- api.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/api.js b/api.js index 9658150..511bc29 100644 --- a/api.js +++ b/api.js @@ -1,4 +1,10 @@ -const fetch = require('node-fetch') +const _nodeFetch = require('node-fetch') +// On Node 18+ (notably Node 24), node-fetch@2's gzip (Gunzip) decode throws +// "FetchError: ... Premature close" on the way my.leviton.com closes responses, +// which escalates to an uncaughtException and crash-loops the whole bridge. +// Disabling gzip avoids the failing decode path; responses come back uncompressed. +// See https://github.com/tabrindle/homebridge-leviton/issues/52 +const fetch = (url, opts = {}) => _nodeFetch(url, { compress: false, ...opts }) const SockJS = require('sockjs-client') const baseURL = 'https://my.leviton.com/api'