fix(gateway): prevent background process notifications from triggering false pairing requests - #5985
Conversation
…g false pairing requests When a background process with notify_on_complete=True finishes, the gateway injects a synthetic MessageEvent to notify the session. This event was constructed without user_id, causing _is_user_authorized() to reject it and — for DM-origin sessions — trigger the pairing flow, sending "Hi~ I don't recognize you yet!" with a pairing code to the chat owner. Add an `internal` flag to MessageEvent that bypasses authorization checks for system-generated synthetic events. Only the process watcher sets this flag; no external/adapter code path can produce it. Includes 4 regression tests covering the fix and the normal pairing path.
|
Friendly bump on this PR in case it fell through the cracks \u2014 would love a review when someone has a minute. Thanks! |
|
We're also hitting this bug. When running Claude Code CLI or Codex CLI via Reproduction: any Root cause confirmed: the synthetic Would love to see this merged — the |
|
Me too, I was going to do the PR but found this here. This feature is awaited for me, and this fix is needed. I will be running from this PR until this gets merged. |
|
Merged via PR #6434. Your commit was cherry-picked onto current main with your authorship preserved in git log. Added a small follow-up fix for test env var isolation. Thanks @xingkongliang! |
Summary
notify_on_complete=Truefinishes, the gateway injects a syntheticMessageEventto notify the session. This event was constructed withoutuser_id, causing_is_user_authorized()to reject it and trigger the DM pairing flow — sending "Hi~ I don't recognize you yet!" with a pairing code to the bot owner's own chat.internalflag toMessageEventthat bypasses authorization for system-generated synthetic events. Only the process watcher sets this flag.Changes
gateway/platforms/base.py: Addinternal: bool = Falsefield toMessageEventgateway/run.py: Skip_is_user_authorized()whenevent.internal is True; setinternal=Trueon process watcher synthetic eventstests/gateway/test_internal_event_bypass_pairing.py: 4 new testsTest plan
test_notify_on_complete_sets_internal_flag— synthetic completion event hasinternal=Truetest_internal_event_bypasses_authorization—_is_user_authorizedis never called for internal eventstest_internal_event_does_not_trigger_pairing— no pairing code generated for internal eventstest_non_internal_event_without_user_triggers_pairing— normal unauthorized DM still triggers pairing (regression guard)test_background_process_notifications.pytests pass🤖 Generated with Claude Code