Skip to content

fix(deps): backport baileys pairing fix (#2727) to main / 2.3.x - #2759

Open
ErgoCodes wants to merge 1 commit into
evolution-foundation:mainfrom
ErgoCodes:fix/baileys-pairing-main
Open

ErgoCodes wants to merge 1 commit into
evolution-foundation:mainfrom
ErgoCodes:fix/baileys-pairing-main

Conversation

@ErgoCodes

@ErgoCodes ErgoCodes commented Oct 19, 2026 •

Copy link
Copy Markdown

📋 Description

Backport of #2727 to the 2.3.x line (main), for users who run 2.3.7 and can't pair new devices.

Since ~2026-07-28 WhatsApp sends a companion_reg_refresh stage during device registration. Baileys acks and discards it, so pair-success is never emitted and linking a new device fails silently. No published Baileys release handles it yet (WhiskeySockets/Baileys#2737).

This PR applies the same fix as #2727 on top of main:

  • bumps baileys 7.0.0-rc.9 → 7.0.0-rc14
  • adds patch-package (+ postinstall) and patches/baileys+7.0.0-rc14.patch, vendoring:
    • Baileys#2765: handle companion_reg_refresh (restores pairing)
    • Baileys#2602: guard link_code_companion_reg against notifications missing the crypto fields
  • Dockerfile: copies patches/ before npm install so the patch is applied in the image

All credit for the patch goes to @cloviscoli (#2727); this only adapts it to main, which doesn't have the patches/ setup that develop has.

🔗 Related Issue

Related: #2727, WhiskeySockets/Baileys#2737

🧪 Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)

🧪 Testing

  • Manual testing completed
  • Functionality verified in development environment
  • No breaking changes introduced

Built the Docker image from this branch and ran it in a real deployment: QR pairing works again and inbound/outbound messages flow end-to-end (n8n webhook integration).

✅ Checklist

  • I have performed a self-review of my code
  • My changes generate no new warnings
  • I have manually tested my changes thoroughly

📝 Additional Notes

Once Baileys ships a release with these fixes, the patch and patch-package can be dropped in favor of a plain version bump.

Summary by Sourcery

Restore new-device pairing compatibility by updating Baileys and applying the required registration fixes.

Bug Fixes:

  • Restore WhatsApp device pairing by handling the newer companion registration refresh stage.
  • Prevent pairing failures caused by registration notifications that lack expected cryptographic fields.

Enhancements:

  • Update Baileys to 7.0.0-rc14 and apply the required upstream fixes through a vendored patch.

Build:

  • Add patch-package installation hooks and ensure Docker builds include the vendored Baileys patch.

…iring

Backports evolution-foundation#2727 onto the 2.3.7 tag
(avoids the licensing gate present on develop/2.4.0).
@sourcery-ai

sourcery-ai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

This backport upgrades Baileys to rc14 and uses patch-package to vendor the companion_reg_refresh pairing fix plus a guard for malformed link-code notifications, with Docker build changes ensuring the patch is present before installation; reviewers should focus on patch correctness against rc14, lockfile integrity, install/build behavior, and pairing and messaging regression coverage.

Sequence diagram for repaired device pairing

sequenceDiagram
    actor User
    participant EvolutionAPI
    participant Baileys
    participant WhatsApp

    User->>EvolutionAPI: Start device pairing
    EvolutionAPI->>Baileys: Register companion device
    WhatsApp-->>Baileys: companion_reg_refresh
    Baileys->>Baileys: Handle companion_reg_refresh
    Baileys-->>EvolutionAPI: pair-success
    EvolutionAPI-->>User: Pairing succeeds
Loading

Flow diagram for applying the Baileys compatibility patch

flowchart LR
    Source["Docker build context"] --> Package["package.json and package-lock.json"]
    Source --> Patches["patches/baileys+7.0.0-rc14.patch"]
    Package --> Install["npm install"]
    Patches --> Install
    Install --> Postinstall["postinstall: patch-package"]
    Postinstall --> Runtime["Baileys rc14 with pairing fixes"]
Loading

File-Level Changes

Change Details Files
Backport the Baileys pairing and notification-safety fixes through a vendored patch.
  • Upgrade Baileys to 7.0.0-rc14.
  • Add a patch-package postinstall hook and patch Baileys to process companion_reg_refresh and guard incomplete link_code_companion_reg notifications.
  • Review the patch contents for compatibility with the rc14 dependency layout and confirm it is applied exactly once during installation.
package.json
package-lock.json
patches/baileys+7.0.0-rc14.patch
Ensure Docker builds apply the vendored dependency patch.
  • Copy the patches directory into the image before npm install.
  • Verify Docker layer ordering leaves patches available when postinstall runs and does not unnecessarily invalidate unrelated dependency layers.
Dockerfile
Validate pairing recovery and end-to-end messaging after the dependency backport.
  • Confirm QR pairing emits pair-success rather than silently stalling.
  • Exercise inbound and outbound message flow, including the n8n webhook integration.
  • Check clean installs and production Docker builds for reproducible patch application.
Dockerfile
package.json
package-lock.json
patches/baileys+7.0.0-rc14.patch

Possibly linked issues

  • #issue: The PR upgrades Baileys to rc14, beyond the issue's verified rc12 fix and requested rc10-or-later version, potentially resolving the decryption failure.

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

@sourcery-ai sourcery-ai Bot 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.

Hey - I've found 1 security issue, and 1 other issue

Security issues:

  • GPL-3.0-only: Open-source license can require releasing the entire application source (link)

Fixed security issues:

  • baileys (link)
  • music-metadata (link)
  • protobufjs (link)
  • package-lock.json (link)
Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="package.json" line_range="81" />
<code_context>
         "audio-decode": "^2.2.3",
         "axios": "^1.7.9",
-        "baileys": "7.0.0-rc.9",
+        "baileys": "7.0.0-rc14",
         "class-validator": "^0.14.1",
         "compression": "^1.7.5",
</code_context>
<issue_to_address>
**QR refreshes exhaust pairing limit**

When enough `companion_reg_refresh` notifications arrive during QR pairing to reach the configured limit, `handleCompanionRegRefresh` re-emits the current QR, and `BaileysStartupService.connectionUpdate` counts each refresh as a new attempt. `qrcode.count` reaches `QRCODE_LIMIT`, so the next refreshed QR is rejected and pairing ends even though the server-issued QR ref is still valid.

Distinguish refreshed QR codes from new attempts so re-emitting the current QR does not increment the attempt count.
</issue_to_address>

### Comment 2
<location path="package-lock.json" line_range="10669-10678" />
<code_context>

</code_context>
<issue_to_address>
**security (license/libsignal):** GPL-3.0-only: Open-source license can require releasing the entire application source

This `GPL-3.0-only` open-source license can impose strong copyleft or non-commercial obligations that may require releasing your full application source code or restrict commercial use, depending on how the code is used or distributed

*Source: trivy*
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 2 findings to address first, and a server refresh now replaces and persists the adv secret used in the pairing QR, so a faulty refresh handler could disrupt device linking or affect the authentication material used during pairing. Reverting removes the handler but does not restore secrets already saved, though pairing can generally be retried.

Blocking findings: package.json:81, package-lock.json:10678


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread package.json
"audio-decode": "^2.2.3",
"axios": "^1.7.9",
"baileys": "7.0.0-rc.9",
"baileys": "7.0.0-rc14",

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.

🟡 Medium · QR refreshes exhaust pairing limit

When enough companion_reg_refresh notifications arrive during QR pairing to reach the configured limit, handleCompanionRegRefresh re-emits the current QR, and BaileysStartupService.connectionUpdate counts each refresh as a new attempt. qrcode.count reaches QRCODE_LIMIT, so the next refreshed QR is rejected and pairing ends even though the server-issued QR ref is still valid.

Distinguish refreshed QR codes from new attempts so re-emitting the current QR does not increment the attempt count.

Prompt for AI agents
In `package.json` at line 81:

**QR refreshes exhaust pairing limit**

When enough `companion_reg_refresh` notifications arrive during QR pairing to reach the configured limit, `handleCompanionRegRefresh` re-emits the current QR, and `BaileysStartupService.connectionUpdate` counts each refresh as a new attempt. `qrcode.count` reaches `QRCODE_LIMIT`, so the next refreshed QR is rejected and pairing ends even though the server-issued QR ref is still valid.

Distinguish refreshed QR codes from new attempts so re-emitting the current QR does not increment the attempt count.

Comment thread package-lock.json
Comment on lines 10669 to 10678
"node_modules/libsignal": {
"name": "@whiskeysockets/libsignal-node",
"version": "2.0.1",
"resolved": "git+ssh://git@github.com/whiskeysockets/libsignal-node.git#1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/libsignal/-/libsignal-6.0.0.tgz",
"integrity": "sha512-d/5V3YFtDljbFMufz4ncyUYGYhJl+vzAe+c2EFFBQ6bz1h8Q3IOMEGXYMzlibU60I+e8GagMMpji18iez3P1hA==",
"license": "GPL-3.0",
"dependencies": {
"curve25519-js": "^0.0.4",
"protobufjs": "6.8.8"
}
},
"node_modules/libsignal/node_modules/@types/node": {
"version": "10.17.60",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
"integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==",
"license": "MIT"
},
"node_modules/libsignal/node_modules/long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
"license": "Apache-2.0"
},
"node_modules/libsignal/node_modules/protobufjs": {
"version": "6.8.8",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz",
"integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
"hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
"@protobufjs/codegen": "^2.0.4",
"@protobufjs/eventemitter": "^1.1.0",
"@protobufjs/fetch": "^1.1.0",
"@protobufjs/float": "^1.0.2",
"@protobufjs/inquire": "^1.1.0",
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.0",
"@types/long": "^4.0.0",
"@types/node": "^10.1.0",
"long": "^4.0.0"
},
"bin": {
"pbjs": "bin/pbjs",
"pbts": "bin/pbts"
"protobufjs": "^7.5.5"
}
},

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.

security (license/libsignal): GPL-3.0-only: Open-source license can require releasing the entire application source

This GPL-3.0-only open-source license can impose strong copyleft or non-commercial obligations that may require releasing your full application source code or restrict commercial use, depending on how the code is used or distributed

Source: trivy

This branch has not been deployed

No deployments
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.

1 participant