Skip to content

Conversation

@kauenzo
Copy link

@kauenzo kauenzo commented Jan 23, 2026

πŸ“‹ Description

πŸ”— Related Issue

Closes #(issue_number)

πŸ§ͺ Type of Change

  • πŸ› Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • πŸ’₯ Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • πŸ“š Documentation update
  • πŸ”§ Refactoring (no functional changes)
  • ⚑ Performance improvement
  • 🧹 Code cleanup
  • πŸ”’ Security fix

πŸ§ͺ Testing

  • Manual testing completed
  • Functionality verified in development environment
  • No breaking changes introduced
  • Tested with different connection types (if applicable)

πŸ“Έ Screenshots (if applicable)

βœ… Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have manually tested my changes thoroughly
  • I have verified the changes work with different scenarios
  • Any dependent changes have been merged and published

πŸ“ Additional Notes

Summary by Sourcery

Handle WhatsApp Baileys connection closures more safely to avoid blocking initial QR code generation and improve reconnection logging.

Bug Fixes:

  • Prevent infinite reconnection loop when the initial WhatsApp connection closes before QR code generation.

Enhancements:

  • Add informative logging when reconnecting after connection loss and when skipping reconnection for specific status codes.

Copilot AI review requested due to automatic review settings January 23, 2026 18:57
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 23, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts WhatsApp Baileys connection-close handling to avoid reconnect loops during initial QR setup and adds clearer logging around reconnection decisions.

Sequence diagram for WhatsApp Baileys connection close and reconnection logic

sequenceDiagram
  participant BaileysStartupService
  participant WhatsAppSocket
  participant Logger

  WhatsAppSocket->>BaileysStartupService: connection.update(connection = close, lastDisconnect)
  BaileysStartupService->>BaileysStartupService: read statusCode from lastDisconnect
  BaileysStartupService->>BaileysStartupService: isInitialConnection = !instance.wuid && (instance.qrcode.count == 0)
  alt Initial connection (waiting for QR)
    BaileysStartupService->>Logger: info(Initial connection closed, waiting for QR code generation...)
    BaileysStartupService-->>WhatsAppSocket: do not reconnect
  else Non initial connection
    BaileysStartupService->>BaileysStartupService: shouldReconnect = !codesToNotReconnect.includes(statusCode)
    alt shouldReconnect
      BaileysStartupService->>Logger: warn(Connection lost, reconnecting...)
      BaileysStartupService->>BaileysStartupService: connectToWhatsapp(phoneNumber)
    else shouldNotReconnect
      BaileysStartupService->>Logger: info(Skipping reconnection for statusCode in codesToNotReconnect)
      BaileysStartupService->>BaileysStartupService: sendDataWebhook(Events.STATUS_INSTANCE, payload)
    end
  end
Loading

Updated class diagram for BaileysStartupService connection close handling

classDiagram
  class ChannelStartupService {
  }

  class BaileysStartupService {
    - any instance
    - any phoneNumber
    - any logger
    + handleConnectionClose(connection, lastDisconnect) void
    + connectToWhatsapp(phoneNumber) Promise
    + sendDataWebhook(event, payload) void
  }

  BaileysStartupService --|> ChannelStartupService

  class Instance {
    + string name
    + string wuid
    + Qrcode qrcode
  }

  class Qrcode {
    + number count
  }

  class Events {
    <<enumeration>>
    STATUS_INSTANCE
  }

  BaileysStartupService o-- Instance : instance
  BaileysStartupService ..> Events : uses
  BaileysStartupService ..> Qrcode : reads count
Loading

File-Level Changes

Change Details Files
Prevent reconnection loop when the initial WhatsApp connection closes before QR code generation.
  • Determine if the connection close event corresponds to an initial connection by checking for missing instance wuid and zero QR code count.
  • Short-circuit the close handler when it is an initial connection, logging an informational message and skipping reconnect logic.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
Improve observability and behavior when deciding whether to reconnect after a disconnect.
  • Log a warning message when reconnecting due to a connection loss with a reconnectable status code.
  • Log an informational message when skipping reconnection because the status code is in the non-reconnect list, before sending the STATUS_INSTANCE webhook.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The isInitialConnection detection mixes !this.instance.wuid with a qrcode?.count check inline; consider encapsulating this in a well-named helper (e.g. isWaitingForInitialQr()) or using an explicit state flag so the semantics are clearer and less fragile if the instance properties change in the future.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `isInitialConnection` detection mixes `!this.instance.wuid` with a `qrcode?.count` check inline; consider encapsulating this in a well-named helper (e.g. `isWaitingForInitialQr()`) or using an explicit state flag so the semantics are clearer and less fragile if the instance properties change in the future.

## Individual Comments

### Comment 1
<location> `src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts:432-436` </location>
<code_context>
+      
+      // FIX: Do not reconnect if it's the initial connection (waiting for QR code)
+      // This prevents infinite loop that blocks QR code generation
+      const isInitialConnection = !this.instance.wuid && (this.instance.qrcode?.count ?? 0) === 0;
+      
+      if (isInitialConnection) {
+        this.logger.info('Initial connection closed, waiting for QR code generation...');
+        return;
+      }
+      
</code_context>

<issue_to_address>
**issue (bug_risk):** Early return on initial connection may skip other important close-handling logic (e.g., status notifications).

Because this returns early when `isInitialConnection` is true, none of the later close-handling logic runs (including the `STATUS_INSTANCE` webhook in the non-reconnect path). If callers expect that status even on initial connection close, this can break monitoring/state tracking. You might instead still emit the appropriate status event here, or refactor so only the reconnect loop is skipped while other close-handling remains consistent.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click πŸ‘ or πŸ‘Ž on each comment and I'll use the feedback to improve your reviews.

Comment on lines +432 to +436
const isInitialConnection = !this.instance.wuid && (this.instance.qrcode?.count ?? 0) === 0;

if (isInitialConnection) {
this.logger.info('Initial connection closed, waiting for QR code generation...');
return;
Copy link
Contributor

Choose a reason for hiding this comment

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

issue (bug_risk): Early return on initial connection may skip other important close-handling logic (e.g., status notifications).

Because this returns early when isInitialConnection is true, none of the later close-handling logic runs (including the STATUS_INSTANCE webhook in the non-reconnect path). If callers expect that status even on initial connection close, this can break monitoring/state tracking. You might instead still emit the appropriate status event here, or refactor so only the reconnect loop is skipped while other close-handling remains consistent.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR attempts to fix an infinite reconnection loop that blocks QR code generation during initial WhatsApp connection. It adds a check to prevent automatic reconnection when a connection closes during the initial connection phase (before a user is authenticated). The PR also adds logging for better visibility into connection state changes and reconnection decisions.

Changes:

  • Added isInitialConnection check to prevent reconnection during initial connection phase
  • Added logging statements for reconnection attempts, skipped reconnections, and initial connection closures

πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// FIX: Do not reconnect if it's the initial connection (waiting for QR code)
// This prevents infinite loop that blocks QR code generation
const isInitialConnection = !this.instance.wuid && (this.instance.qrcode?.count ?? 0) === 0;
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The condition (this.instance.qrcode?.count ?? 0) === 0 only prevents reconnection when the connection closes before the first QR code is generated. However, based on the comment "Do not reconnect if it's the initial connection (waiting for QR code)", it appears the intent is to prevent reconnection during the entire QR code phase (count can be 1 to LIMIT while waiting for the user to scan). After the first QR code is generated (count becomes 1), if the connection closes, this check will fail and reconnection will still trigger, potentially causing the infinite loop mentioned in the comment. Consider using !this.instance.wuid alone (which indicates no authenticated user) or checking if count is below the LIMIT to cover all initial connection scenarios.

Suggested change
const isInitialConnection = !this.instance.wuid && (this.instance.qrcode?.count ?? 0) === 0;
const isInitialConnection = !this.instance.wuid;

Copilot uses AI. Check for mistakes.
Comment on lines 426 to 447
if (connection === 'close') {
const statusCode = (lastDisconnect?.error as Boom)?.output?.statusCode;
const codesToNotReconnect = [DisconnectReason.loggedOut, DisconnectReason.forbidden, 402, 406];

// FIX: Do not reconnect if it's the initial connection (waiting for QR code)
// This prevents infinite loop that blocks QR code generation
const isInitialConnection = !this.instance.wuid && (this.instance.qrcode?.count ?? 0) === 0;

if (isInitialConnection) {
this.logger.info('Initial connection closed, waiting for QR code generation...');
return;
}

const shouldReconnect = !codesToNotReconnect.includes(statusCode);
if (shouldReconnect) {
this.logger.warn(`Connection lost (status: ${statusCode}), reconnecting...`);
await this.connectToWhatsapp(this.phoneNumber);
} else {
this.logger.info(
`Skipping reconnection for status code ${statusCode} (code is in codesToNotReconnect list)`,
);
this.sendDataWebhook(Events.STATUS_INSTANCE, {
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The PR description is incomplete - it only contains the template without filling in the actual details. Please provide a description of what issue this PR is addressing, what the root cause was, and how this fix resolves it. This will help reviewers understand the context and validate that the solution is correct.

Copilot uses AI. Check for mistakes.
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.

2 participants