diff --git a/src/Utils/decode-wa-message.ts b/src/Utils/decode-wa-message.ts index 5ebf5520..24328675 100644 --- a/src/Utils/decode-wa-message.ts +++ b/src/Utils/decode-wa-message.ts @@ -454,19 +454,40 @@ export const decryptMessageNode = ( ...(isRetryExhausted && { retriesExhausted: true, attempts: err.attempts }) } - // Smart logging based on error type and retry status + // Smart logging based on error type and retry status. + // + // PERF NOTE: under WhatsApp's LID/DSM rollout, own DSM messages flood + // the inbound pipeline with Bad MAC / "Key used already" / "No session + // record" errors *every* time the auth state has a session in the + // legacy `_1.0` format that no longer matches the LID-addressed + // envelope. Logging the full errorContext (key + jid + err) per failed + // attempt as warn-level produces tens of JSON lines/sec, which + // saturates stdout in pm2 (synchronous writes to a full pipe block the + // event loop). The clean `🔐 Bad MAC Error | JID: …` line emitted by + // the console.error interceptor in src/index.ts already gives an + // operator-visible signal — the duplicated pino line was pure noise. + // + // We now only emit warn-level when retries are exhausted (rare, + // actionable). Per-attempt detail is still available at debug level + // (BAILEYS_LOG_LEVEL=debug) for active troubleshooting. + const slimErrorContext = { + msgId: fullMessage.key?.id, + jid: fullMessage.key?.remoteJid, + err: slimErr, + attempts: isRetryExhausted ? err.attempts : 1 + } + if (isCorrupted) { - // Corrupted session errors are expected and auto-recovered - // Only log as ERROR if retries exhausted, otherwise WARN on first attempt + // Corrupted session errors are expected — Signal Protocol auto-recovers + // via retry receipt → pkmsg → new session. // eslint-disable-next-line max-depth if (isRetryExhausted) { - logger.error( - errorContext, + logger.warn( + slimErrorContext, `⚠️ Session corrupted after ${err.attempts} attempts. Retry+pkmsg flow will recover.` ) } else { - // First occurrence - log as warning since auto-recovery will attempt - logger.warn(errorContext, '⚠️ Corrupted session detected - attempting auto-recovery') + logger.debug(errorContext, '⚠️ Corrupted session detected - attempting auto-recovery') } // Session cleanup is deferred to retry exhaustion (safety net). @@ -479,7 +500,7 @@ export const decryptMessageNode = ( // Session record errors are transient - retry should handle them // eslint-disable-next-line max-depth if (isRetryExhausted) { - logger.error(errorContext, `Failed to decrypt: No session record found after ${err.attempts} attempts`) + logger.warn(slimErrorContext, `Failed to decrypt: No session record found after ${err.attempts} attempts`) } else { logger.debug(errorContext, 'No session record - will retry') }