Skip to content

fix: do not announce presence on partial creds.update - #2740

Open
heitorarns wants to merge 1 commit into
WhiskeySockets:masterfrom
heitorarns:fix/presence-on-partial-creds-update
Open

fix: do not announce presence on partial creds.update#2740
heitorarns wants to merge 1 commit into
WhiskeySockets:masterfrom
heitorarns:fix/presence-on-partial-creds-update

Conversation

@heitorarns

@heitorarns heitorarns commented Jul 30, 2026

Copy link
Copy Markdown

Fixes the root cause behind #2553. The same diagnosis and the same one-line fix were posted in
#2627 and acknowledged there, but that issue was closed by the stale bot rather than applied, so
master still carries the code.

The bug

Socket/socket.ts announces the push name on every creds.update:

const name = update.me?.name
if (creds.me?.name !== name) {
  sendNode({ tag: 'presence', attrs: { name: name! } })

A partial update carries no me — pre-key churn, and the updates emitted while handling incoming
messages — so name is undefined, and creds.me?.name !== undefined is true for any session
that has a stored push name. The name! assertion is precisely the assumption that fails.

What then goes out is a typeless <presence />: encodeBinaryNode filters out undefined
attributes, so nothing is left. And a presence without a type means available — the inbound
handler in Socket/chats.ts applies exactly that rule:

lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available'

The result is an account marked online on ordinary credential churn, including once per
incoming message
, whatever markOnlineOnConnect is set to. Nothing is logged, because the send
succeeds. While the account is online, WhatsApp stops pushing notifications to the primary phone
— which is the symptom people actually report.

Reproducing it without sending anything

Read-only client, markOnlineOnConnect: false, already paired:

  1. Leave the primary phone locked and untouched; confirm from a third account that the number
    reads as offline.
  2. Send a message to it from a second account.
  3. The number goes online for several minutes, with the phone never opened. Repeating step 2
    keeps it online.

The change

Guard on a non-empty string. Genuine push-name updates are still announced; partial credential
patches are not. The ! assertion goes with it, since the guard now proves the type.

Verification

  • npm install (which runs preparetsc -P tsconfig.build.json) compiles clean.
  • prettier --check src/Socket/socket.ts passes.
  • I did not add a test: exercising this path means standing up the whole makeSocket factory, and
    I did not want to bolt fragile scaffolding onto an unfamiliar suite for a two-condition guard.
    Happy to add one if you would like it, in whatever shape you prefer.

Summary by cubic

Stop announcing presence on partial creds.update to prevent unintended “online” status and missed phone notifications. Only send a presence update when the push name actually changes.

  • Bug Fixes
    • Guard in src/Socket/socket.ts: send presence only if update.me?.name is a non-empty string and differs from creds.me?.name.
    • Remove the non-null assertion and pass name directly to attrs.
    • Avoids sending a typeless <presence /> on partial updates, which previously marked accounts as online during pre-key churn or incoming message handling.

Written for commit c9d5b42. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved presence updates by ignoring incomplete or empty name changes.
    • Prevented unnecessary presence notifications when the displayed name has not changed.

The `creds.update` handler announces the push name whenever
`creds.me?.name !== update.me?.name`. Partial updates carry no `me` — pre-key
churn, and the updates emitted while handling incoming messages — so `name` is
`undefined` and the comparison is true for any session that has a stored push
name. The `name!` assertion is exactly that assumption.

What goes out is a typeless `<presence />`, because encodeBinaryNode filters out
undefined attributes. A presence without a type reads as available; the inbound
handler in Socket/chats.ts applies the same rule:
`attrs.type === 'unavailable' ? 'unavailable' : 'available'`.

So the account is marked online on ordinary credential churn — including once
per incoming message — no matter what `markOnlineOnConnect` is set to. While it
is online, WhatsApp stops pushing notifications to the primary phone, which is
the symptom users actually notice.

Guarding on a non-empty string keeps genuine push-name updates announced and
drops the rest. The assertion goes with it, since the guard now proves the type.

Reported in WhiskeySockets#2553. Same root cause and the same one-line fix were identified in
WhiskeySockets#2627, which was closed by the stale bot rather than applied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@whiskeysockets-bot

Copy link
Copy Markdown
Contributor

Thanks for opening this pull request and contributing to the project!

The next step is for the maintainers to review your changes. If everything looks good, it will be approved and merged into the main branch.

In the meantime, anyone in the community is encouraged to test this pull request and provide feedback.

✅ How to confirm it works

If you’ve tested this PR, please comment below with:

Tested and working ✅

This helps us speed up the review and merge process.

📦 To test this PR locally:

# NPM
npm install @whiskeysockets/baileys@heitorarns/Baileys#fix/presence-on-partial-creds-update

# Yarn (v2+)
yarn add @whiskeysockets/baileys@heitorarns/Baileys#fix/presence-on-partial-creds-update

# PNPM
pnpm add @whiskeysockets/baileys@heitorarns/Baileys#fix/presence-on-partial-creds-update

If you encounter any issues or have feedback, feel free to comment as well.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The credentials update handler now emits push-name presence updates only when me.name is a non-empty string that differs from the stored name.

Changes

Push name validation

Layer / File(s) Summary
Validate push name before presence emission
src/Socket/socket.ts
The creds.update handler ignores missing or empty names and emits presence attributes using the validated name when it changes.

Estimated code review effort: 2 (Simple) | ~5 minutes

Suggested reviewers: purpshell, jlucaso1

Poem

I’m a rabbit guarding names,
Empty whispers stay away.
Changed names hop through presence,
Neatly tagged for sharing’s day.
Thump, thump—updates now behave!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main fix: suppressing presence announcements on partial creds.update events.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/Socket/socket.ts (1)

1054-1060: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add integration coverage for push-name presence emission.

This changes wire-level protocol behavior but adds no test. Cover partial updates without me, empty names, unchanged names, and valid changed names, asserting whether sendNode emits the expected presence stanza.

As per coding guidelines, “New protocol paths or stanza handlers should have integration tests mocking binary nodes, not e2e tests.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Socket/socket.ts` around lines 1054 - 1060, Add integration coverage for
the push-name presence logic around the updated pushName path, using mocked
binary nodes and observing sendNode calls. Verify that partial updates without
creds.me and empty names do not emit presence, unchanged names do not emit
presence, and valid changed names emit the expected presence stanza with the
name attribute.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/Socket/socket.ts`:
- Around line 1054-1060: Add integration coverage for the push-name presence
logic around the updated pushName path, using mocked binary nodes and observing
sendNode calls. Verify that partial updates without creds.me and empty names do
not emit presence, unchanged names do not emit presence, and valid changed names
emit the expected presence stanza with the name attribute.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c5a4c3bd-a336-4fc1-b1c0-bdd5481c37b5

📥 Commits

Reviewing files that changed from the base of the PR and between 74af8ee and c9d5b42.

📒 Files selected for processing (1)
  • src/Socket/socket.ts

@cubic-dev-ai cubic-dev-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.

No issues found across 1 file

Re-trigger cubic

ayusc added a commit to ayusc/Baileys that referenced this pull request Aug 9, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This PR is stale because it has been open for 14 days with no activity. Remove the stale label or comment or this will be closed in 14 days

@github-actions github-actions Bot added the Stale label Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants