Skip to content

Fix 463 MissingTcToken recovery flow and dedupe concurrent token re-issuance#2517

Open
Kunboruto20 wants to merge 3 commits intoWhiskeySockets:masterfrom
Kunboruto20:master
Open

Fix 463 MissingTcToken recovery flow and dedupe concurrent token re-issuance#2517
Kunboruto20 wants to merge 3 commits intoWhiskeySockets:masterfrom
Kunboruto20:master

Conversation

@Kunboruto20
Copy link
Copy Markdown

@Kunboruto20 Kunboruto20 commented May 1, 2026

This PR improves how Baileys handles ACK error 463 (MissingTcToken).

What changed
Added a self-healing recovery path in messages-recv when the server returns ACK error 463.

On 463, the client now:

Resolves the correct storage and issuance JIDs,

Calls issuePrivacyTokens(...),

Persists the returned token via storeTcTokensFromIqResult(...).

Added an in-flight dedupe set (inFlight463Recoveries) to avoid starting multiple recovery jobs for the same contact at the same time.

Kept this flow non-blocking and preserved existing behavior (no automatic message resend loop).

Why
Previously, 463 was mostly logged, which could leave the session stuck without a refreshed token for that contact.
With this change, the client proactively recovers token state so subsequent sends can succeed more reliably.

Safety / behavior notes
No message auto-retry was introduced (to avoid retry loops and extra reachout pressure).

Recovery is best-effort and isolated; failures are logged and dedupe state is always released in finally.

Testing
Ran focused token tests:

npm test -- --runInBand src/tests/Utils/tc-token.test.ts

Result: PASS (all tests passed).

Summary by CodeRabbit

  • Bug Fixes
    • Improved resilience for missing token errors: the system now automatically initiates an asynchronous recovery to re-issue required privacy tokens, persist them, and log outcomes. Concurrent recovery attempts are deduplicated to avoid redundancy. Recovery markers are reliably cleared on completion or failure to allow future retries.

…e-hour-on-repository

Handle 463 MissingTcToken ack by issuing and storing TC tokens (deduped)
@whiskeysockets-bot
Copy link
Copy Markdown
Contributor

whiskeysockets-bot commented May 1, 2026

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@Kunboruto20/Baileys#master

# Yarn (v2+)
yarn add @whiskeysockets/baileys@Kunboruto20/Baileys#master

# PNPM
pnpm add @whiskeysockets/baileys@Kunboruto20/Baileys#master

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: add3c529-8742-4ea7-80c7-943489a431a6

📥 Commits

Reviewing files that changed from the base of the PR and between f2a3b8e and a482bd0.

📒 Files selected for processing (1)
  • src/Socket/messages-recv.ts

📝 Walkthrough

Walkthrough

When an ack returns error code 463 (MissingTcToken), the receiver now launches an asynchronous recovery: it deduplicates concurrent recoveries per target JID, resolves storage and issuance JIDs, issues privacy tokens for the issuance JID, persists tokens to the TC store, and always clears the in-flight marker.

Changes

Cohort / File(s) Summary
TC Token Recovery Handler
src/Socket/messages-recv.ts
Added asynchronous recovery flow for SERVER_ERROR_CODES.MissingTcToken (463). Introduces inFlight463Recoveries to dedupe concurrent recoveries, resolves storage/issuance JIDs, issues privacy tokens with current timestamp, persists tokens to TC store, and ensures cleanup in a finally block.

Sequence Diagram(s)

sequenceDiagram
    participant Receiver as Receiver
    participant Dedup as Dedup_Set
    participant JIDResolver as JID_Resolver
    participant TokenIssuer as Token_Issuer
    participant TCStore as TC_Store
    participant Logger as Logger

    Receiver->>Receiver: Detect 463 MissingTcToken
    Receiver->>Dedup: Check `inFlight463Recoveries`
    alt already in-flight
        Dedup-->>Receiver: Skip recovery
    else start recovery
        Dedup->>Dedup: Add JID to set
        Receiver->>JIDResolver: Resolve storage & issuance JIDs
        JIDResolver-->>Receiver: Return resolved JIDs
        Receiver->>TokenIssuer: Issue privacy tokens (timestamped)
        TokenIssuer-->>Receiver: Return tokens
        Receiver->>TCStore: Persist tokens to TC store
        TCStore-->>Receiver: Ack persist
        Receiver->>Logger: Log success/failure
        Receiver->>Dedup: Remove JID from set (finally)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A missing token caused quite a fuss,
I hopped in to fix it without a muss.
Resolve, issue, store — then clear the trace,
One deduped recovery, tidy and in place. ✨

🚥 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 accurately describes the main changes: fixing the 463 MissingTcToken recovery flow and deduplicating concurrent token re-issuance via the inFlight463Recoveries mechanism.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Socket/messages-recv.ts`:
- Around line 1574-1579: The storeTcTokensFromIqResult call in this branch
stores tokens but never updates the TC-token index; after awaiting
storeTcTokensFromIqResult({ result, fallbackJid: tcStorageJid, keys:
authState.keys, getLIDForPN }) add a call to trackTcTokenJid using the recovered
JID (use result.jid if present, otherwise tcStorageJid) and include the
token/key context (e.g., authState.keys) so the in-memory/persisted index is
updated like the other sites that call storeTcTokensFromIqResult.
- Around line 1560-1584: The dedupe set in the 463 recovery flow currently keys
by raw attrs.from (ackFrom) which allows duplicates for the same peer presented
as PN vs LID; compute a canonical key before checking/adding to
inFlight463Recoveries by calling jidNormalizedUser(ackFrom) or, preferably,
using the resolved tcStorageJid returned by resolveTcTokenJid and use that
canonicalId for the has/add/delete and log entries; specifically, call
resolveTcTokenJid(ackFrom, getLIDForPN) early, set const canonicalId =
tcStorageJid (or jidNormalizedUser(ackFrom) if resolve fails), then replace all
uses of ackFrom in inFlight463Recoveries.has/add/delete and the logger debug
context with canonicalId while still passing ackFrom to the downstream
resolution/issuance calls where the raw JID is required.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e2eb9ce0-387d-432b-aa49-0860ea6a8313

📥 Commits

Reviewing files that changed from the base of the PR and between ca61ac1 and f2a3b8e.

📒 Files selected for processing (1)
  • src/Socket/messages-recv.ts

Comment thread src/Socket/messages-recv.ts
Comment thread src/Socket/messages-recv.ts
Copy link
Copy Markdown
Contributor

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

2 issues found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/Socket/messages-recv.ts">

<violation number="1" location="src/Socket/messages-recv.ts:1561">
P2: The dedupe set `inFlight463Recoveries` is keyed on the raw `attrs.from` value, but the same contact can appear under different JID forms (PN vs LID). When that happens, parallel recovery requests will be issued for the same underlying contact, defeating the deduplication. Key the set by the resolved `tcStorageJid` (or at minimum `jidNormalizedUser(ackFrom)`) instead.</violation>

<violation number="2" location="src/Socket/messages-recv.ts:1574">
P2: This `storeTcTokensFromIqResult` call does not pass `onNewJidStored: trackTcTokenJid`, unlike the other call sites in this file. The recovered token will be persisted but the contact won't be added to the TC token index, causing later prune/index-save passes to miss it.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/Socket/messages-recv.ts
Comment thread src/Socket/messages-recv.ts
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants