From 4a58c014ca750fc73002e145f733492e3c0d6630 Mon Sep 17 00:00:00 2001 From: Renato Alcara Date: Sat, 2 May 2026 00:40:13 -0300 Subject: [PATCH] fix(socket): give init queries headroom + add CB kill-switch env var MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Production report: after scanning QR for a brand-new channel the user gets "WhatsApp não inicializado" / "1 sem ativação" because the `socket-query` circuit breaker opens during the post-pairing `init queries` (USync, device-list, app-state-sync). Existing channels are unaffected — only fresh pairings trip the CB because their first round of metadata fetches is slow (no warm server-side cache for the client, larger payload). Two small changes: 1. Bump the `socket-query` CB timeout floor to 120 s (was `defaultQueryTimeoutMs || 60000`, which evaluated to 30 s in this build). The per-query `waitForMessage` timeout still enforces a tighter bound for individual operations — this only widens the *cumulative* window the CB watches before tripping. 2. Add `BAILEYS_DISABLE_CIRCUIT_BREAKER=true` env var as an emergency kill-switch so operators can disable all three CBs (query, connection, prekey) without touching code or rebuilding zpro. The default `enableCircuitBreaker` config flag still works for callers that pass it in code. No behavior change for existing channels under normal load — the bump only matters when init queries actually take longer than 30 s. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Socket/socket.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 0fdc80d6..7cb99e4c 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -107,20 +107,31 @@ export const makeSocket = (config: SocketConfig) => { const enableUnifiedSession = enableUnifiedSessionConfig !== undefined ? enableUnifiedSessionConfig : shouldEnableUnifiedSession() - // Initialize circuit breakers if enabled + // Initialize circuit breakers if enabled. + // + // Env var override: BAILEYS_DISABLE_CIRCUIT_BREAKER=true completely disables + // all three circuit breakers without requiring a code change. Useful when the + // query CB is opening on slow `init queries` after a fresh QR pairing — those + // initial USync / device-list / app-state queries can legitimately take longer + // than the per-call timeout when the auth state is fresh and the server has + // no warm caches for this client. + const envDisableCB = process.env.BAILEYS_DISABLE_CIRCUIT_BREAKER === 'true' let queryCircuitBreaker: CircuitBreaker | undefined let connectionCircuitBreaker: CircuitBreaker | undefined let preKeyCircuitBreaker: CircuitBreaker | undefined - if (enableCircuitBreaker) { - // Circuit breaker for query operations (most critical) + if (enableCircuitBreaker && !envDisableCB) { + // Circuit breaker for query operations (most critical). + // timeout=120s gives `init queries` (USync, device-list, app-state-sync) + // enough room on fresh QR pairings; the per-query timeout in waitForMessage + // already enforces a tighter bound for individual operations. queryCircuitBreaker = createConnectionCircuitBreaker({ name: 'socket-query', failureThreshold: 5, failureWindow: 60000, resetTimeout: 30000, successThreshold: 2, - timeout: defaultQueryTimeoutMs || 60000, + timeout: Math.max(defaultQueryTimeoutMs || 0, 120_000), onStateChange: (from, to) => { logger.info({ from, to }, 'Query circuit breaker state changed') },