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
- Create a channel extension with
pairing adapter defined (e.g., Zalo plugin)
- Register the channel via
api.registerChannel({ plugin, dock })
- Set
dmPolicy: "pairing" in config
- 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
- Pass registry to extensions: Inject the active registry into extension context during registration
- Accept adapter parameter: Modify
upsertChannelPairingRequest to accept an optional pairingAdapter parameter
- Compile extensions: Run extensions from
dist/ instead of source TypeScript
- Shared module resolution: Ensure Bun uses the same module cache as the gateway's Node runtime
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
pairingadapter defined (e.g., Zalo plugin)api.registerChannel({ plugin, dock })dmPolicy: "pairing"in configExpected 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()returnsnullwhen called from extension code because:dist/and sets the registry singletonactiveRegistryvariable indist/plugins/runtime.jsis not shared between module instancesDebug output:
Environment
Logs or screenshots
Potential fixes
upsertChannelPairingRequestto accept an optionalpairingAdapterparameterdist/instead of source TypeScript