Skip to content

[Bug]: Extension channels (like Zalo) cannot use the core pairing system #987

@longmaba

Description

@longmaba

Summary

Extension channels (like Zalo) cannot use the core pairing system because the plugin registry is not accessible from extension code due to ESM module isolation.

Steps to reproduce

  1. Create a channel extension with pairing adapter defined (e.g., Zalo plugin)
  2. Register the channel via api.registerChannel({ plugin, dock })
  3. Set dmPolicy: "pairing" in config
  4. Send a message from an unauthorized user to trigger pairing flow

Expected behavior

The upsertChannelPairingRequest({ channel: "zalo", ... }) call should find the Zalo channel's pairing adapter and create a pairing request.

Actual behavior

Error: Channel zalo does not support pairing``

Root cause: getActivePluginRegistry() returns null when called from extension code because:

  • Gateway runs compiled JS from dist/ and sets the registry singleton
  • Extensions run as TypeScript via Bun with a separate ESM module cache
  • The activeRegistry variable in dist/plugins/runtime.js is not shared between module instances

Debug output:

[zalo-debug] Registry exists: false
[zalo-debug] Registry channels count: 0
[zalo-debug] Available channels: telegram, whatsapp, discord, slack, signal, imessage, msteams
[zalo-debug] zaloPlugin found: false, has pairing: false

Environment

  • Clawdbot version: 2026.1.15
  • OS: Windows 11 Pro (Build 26100)
  • Install method: pnpm (dev mode with Bun for TypeScript execution)

Logs or screenshots

[default] Zalo polling error: Error: Channel zalo does not support pairing
at requirePairingAdapter (file:///O:/projects/clawdbot/dist/channels/plugins/pairing.js:15:15)
at Object.upsertChannelPairingRequest (file:///O:/projects/clawdbot/dist/pairing/pairing-store.js:220:5)
at processMessageWithPipeline (O:\projects\clawdbot\extensions\zalo\src\monitor.ts:459:48)

Potential fixes

  1. Pass registry to extensions: Inject the active registry into extension context during registration
  2. Accept adapter parameter: Modify upsertChannelPairingRequest to accept an optional pairingAdapter parameter
  3. Compile extensions: Run extensions from dist/ instead of source TypeScript
  4. Shared module resolution: Ensure Bun uses the same module cache as the gateway's Node runtime

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions