hermes - ✅(Solved) Fix [Bug]: WhatsApp bridge fails to resolve contacts from allowlist when using phone numbers [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#14486Fetched 2026-04-24 06:16:57
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
0
Participants
Timeline (top)
labeled ×4commented ×1cross-referenced ×1mentioned ×1

Error Message

Additional Logs / Traceback (optional)

Root Cause

Message delivery fails because the tool attempts to use the phone-number-based JID format (e.g., [email protected]) which is no longer supported by WhatsApp's API. The correct format is now LID-based (e.g., 77214955630717@lid).

Fix Action

Fix / Workaround

  • WhatsApp now uses LID (Linked ID) instead of phone-number-based JIDs
  • A jidDecode patch was applied to strip the whatsapp: prefix, but LID resolution remains unresolved
  • The channel directory at ~/.hermes/channel_directory.json contains the actual internal IDs
  • The bridge API can be used directly as a workaround: POST http://127.0.0.1:3000/send with {"chatId": "ID", "message": "text"}

PR fix notes

PR #14738: fix(tools): resolve whatsapp phone numbers to lid format

Description (problem / solution / changelog)

What does this PR do?

<!-- Describe the change clearly. What problem does it solve? Why is this approach the right one? -->

This PR fixes a critical bug where AI-initiated tool calls and cron reminders failed to send messages over WhatsApp because they used bare phone numbers instead of the required Linked Identity Device (LID) formats.

Context: JIDs vs. LIDs

1 JID (Jabber ID): The traditional WhatsApp routing identifier. For direct messages, it looks like [phone_number]@s.whatsapp.net. For groups, it looks like [group_id]@g.us.

2 LID (Linked Identity Device): WhatsApp's modern, privacy-focused identifier format (e.g., 77214955630717@lid). The underlying Baileys bridge now strictly enforces this format for newer accounts and multi-device setups.

Why we can't fully ditch JIDs: We must continue supporting JIDs because group chats (@g.us) still rely entirely on the JID format. Additionally, we need to maintain legacy JID fallbacks (@s.whatsapp.net) for older accounts or edge cases where an LID isn't known yet.

The Bug

Incoming messages from WhatsApp to Hermes were working perfectly. This is because the local Baileys bridge natively handles incoming LIDs and automatically maps them to phone numbers for authorization (via allowlist.js). However, the system broke on outgoing messages initiated by the AI (via tools) or by background Cron jobs. These systems only knew the user's bare phone number (e.g., +1234567890). When send_message_tool sent this bare phone number to the bridge, the bridge rejected it because it expects a fully qualified LID or JID.

The Fix

This PR implements a resolution pipeline that bridges the gap between the agent's knowledge (phone numbers) and the bridge's requirements (LIDs):

  1. Resolution Pipeline: Added _resolve_whatsapp_phone_to_jid to the send_message_tool. When a bare phone number is provided, it reads the local bridge session files (~/.hermes/whatsapp/session/lid-mapping-{phone}.json) created during the bridge handshake to gracefully convert the phone number to its proper LID.
  2. Smart Routing: Updated _parse_target_ref and _send_whatsapp to use this pipeline. If an already-valid JID is passed in (containing @lid, @s.whatsapp.net, or @g.us), it passes through untouched.
  3. Fallback Mechanism: If no mapping file exists for a phone number, it safely falls back to the legacy @s.whatsapp.net format.

Comprehensive unit tests were added in test_send_message_tool.py to ensure legacy JIDs, LIDs, group JIDs, and fallback mechanisms are all routed correctly.

Related Issue

<!-- Link the issue this PR addresses. If no issue exists, consider creating one first. -->

Fixes #14486

Type of Change

<!-- Check the one that applies. -->
  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

<!-- List the specific changes. Include file paths for code changes. -->
  • tools/send_message_tool.py: Added _resolve_whatsapp_phone_to_jid and _ensure_whatsapp_jid helpers. Updated _parse_target_ref and _send_whatsapp routing to automatically resolve bare phone numbers and respect valid WhatsApp JIDs.
  • tests/tools/test_send_message_tool.py: Added test class TestWhatsAppPhoneToLidResolution and TestEnsureWhatsAppJid to cover mapping file lookups, legacy fallbacks, and standard JID passthrough.

How to Test

<!-- Steps to verify this change works. For bugs: reproduction steps + proof that the fix works. -->
  1. Ensure your WhatsApp bridge session is active and mapping files exist in ~/.hermes/whatsapp/session/.
  2. Schedule a cron reminder using Hermes over WhatsApp with your bare phone number (e.g. "Remind me to wake up my friend at 6:39 PM").
  3. Wait for the cron job to trigger and observe that the delivery executes successfully instead of throwing a validation error.

Checklist

<!-- Complete these before requesting review. -->

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 14/15

Documentation & Housekeeping

<!-- Check all that apply. It's OK to check "N/A" if a category doesn't apply to your change. -->
  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

<!-- Only fill this out if you're adding a skill. Delete this section otherwise. -->
  • This skill is broadly useful to most users (if bundled) — see Contributing Guide
  • SKILL.md follows the standard format (frontmatter, trigger conditions, steps, pitfalls)
  • No external dependencies that aren't already available (prefer stdlib, curl, existing Hermes tools)
  • I've tested the skill end-to-end: hermes --toolsets skills -q "Use the X skill to do Y"

Screenshots / Logs

<!-- If applicable, add screenshots or log output showing the fix/feature in action. -->

Tested manually as well, by asking the agent to remind me at 18:39 via whatsapp, and it did remind me

Changed files

  • tests/tools/test_send_message_tool.py (modified, +106/-2)
  • tools/send_message_tool.py (modified, +81/-4)

Code Example

Report       https://paste.rs/nzFqY
agent.log    https://paste.rs/5SIMp
gateway.log  https://paste.rs/V6r2K

---
RAW_BUFFERClick to expand / collapse

Bug Description

When attempting to send a WhatsApp message to a contact from the allowlist using their phone number, the send_message tool fails to resolve the target. WhatsApp has migrated to LID (Linked ID) format, breaking phone-number-based JID resolution.

Steps to Reproduce

  1. Configure a contact in the WhatsApp bridge allowlist with their phone number
  2. Ask the agent to send a message to that contact
  3. Observe the resolution failure

Expected Behavior

The bridge should correctly resolve the contact's phone number to their current WhatsApp LID and deliver the message.

Actual Behavior

Message delivery fails because the tool attempts to use the phone-number-based JID format (e.g., [email protected]) which is no longer supported by WhatsApp's API. The correct format is now LID-based (e.g., 77214955630717@lid).

Affected Component

Gateway (Telegram/Discord/Slack/WhatsApp)

Messaging Platform (if gateway-related)

WhatsApp

Debug Report

Report       https://paste.rs/nzFqY
agent.log    https://paste.rs/5SIMp
gateway.log  https://paste.rs/V6r2K

Operating System

macOS 26.4.1

Python Version

3.11.15

Hermes Version

Hermes Agent v0.10.0 (2026.4.16

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

  • WhatsApp now uses LID (Linked ID) instead of phone-number-based JIDs
  • A jidDecode patch was applied to strip the whatsapp: prefix, but LID resolution remains unresolved
  • The channel directory at ~/.hermes/channel_directory.json contains the actual internal IDs
  • The bridge API can be used directly as a workaround: POST http://127.0.0.1:3000/send with {"chatId": "ID", "message": "text"}

Proposed Fix (optional)

Update the send_message tool or WhatsApp bridge to:

  1. Query the channel directory for the correct LID when a phone number is provided
  2. Fall back to direct bridge API calls when LID resolution fails
  3. Add logging to surface resolution failures clearly

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

extent analysis

TL;DR

Update the send_message tool to query the channel directory for the correct LID when a phone number is provided to resolve the target correctly.

Guidance

  • Verify that the channel directory at ~/.hermes/channel_directory.json contains the actual internal IDs for WhatsApp contacts.
  • Use the bridge API directly as a workaround by sending a POST request to http://127.0.0.1:3000/send with the correct LID and message.
  • Consider adding logging to surface resolution failures clearly to aid in debugging.
  • Review the proposed fix steps to update the send_message tool or WhatsApp bridge for a more permanent solution.

Example

No code snippet is provided as the issue does not contain sufficient code context, but the bridge API workaround can be implemented using a tool like curl:

curl -X POST http://127.0.0.1:3000/send -H "Content-Type: application/json" -d '{"chatId": "77214955630717", "message": "Hello, world!"}'

Notes

The provided solution assumes that the channel directory contains the correct LID for the WhatsApp contact and that the bridge API is properly configured.

Recommendation

Apply the workaround using the bridge API until a permanent fix can be implemented, as it allows for message delivery using the correct LID format.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix [Bug]: WhatsApp bridge fails to resolve contacts from allowlist when using phone numbers [1 pull requests, 1 comments, 2 participants]