Conversation
ExternalNamespace was missing context_hooks, so on_dispatch hooks would not fire for tasks dispatched to external applications. Also fixes black formatting issues. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
create_activation passes headers as MutableMapping[str, Any], not dict[str, str]. Values are stringified after hooks run. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests verify: - on_dispatch injects headers during create_activation - No headers injected when no hooks registered - Multiple hooks all get called - on_execute receives activation headers during child_process execution Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| self._producer_factory = producer_factory | ||
| self._router = router | ||
| self._metrics = metrics | ||
| self._context_hooks: list[ContextHook] = context_hooks or [] |
There was a problem hiding this comment.
Falsy or [] breaks hook list reference chain
Medium Severity
The context_hooks or [] pattern in TaskRegistry.__init__ and TaskNamespace.__init__ creates new disconnected empty lists when the incoming list is empty (since [] is falsy in Python). This breaks the reference chain from app.context_hooks through to namespace.context_hooks. The dispatch side reads hooks from self._namespace.context_hooks while the execution side reads from app.context_hooks — so any hooks appended to app.context_hooks after construction will be visible on execution but silently ignored on dispatch. Using if context_hooks is not None instead of the or pattern would preserve empty list references.
Additional Locations (1)
Implement ViewerContextHook that propagates ViewerContext through TaskBroker task headers. On dispatch, the hook reads from the contextvar and injects org_id, user_id, and actor_type into task headers. On execution, it restores the ViewerContext from headers into a viewer_context_scope. This enables implicit identity propagation through async tasks without requiring callsites to manually pass user context. Depends on getsentry/taskbroker#587 for the ContextHook protocol. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>


Relevant context: https://www.notion.so/sentry/RFC-Unified-ViewerContext-via-ContextVar-32f8b10e4b5d81988625cb5787035e02
I think if we want to implicitly pass VC across the wire, we'll need to do these.
to make this work fully implicitly i add hooks to both pack it into context as header on producer side and unpack it on the consumer side automatically.