feat(pyramid): Set user.id on spans when PII is enabled#6606
Conversation
When span streaming is enabled and send_default_pii is true, set the user.id attribute on the segment span using the authenticated user ID from the Pyramid request. Fixes PY-2402 Fixes #6605
| if should_send_default_pii() and has_span_streaming_enabled(client.options): | ||
| current_span = current_scope.streamed_span | ||
| user_id = authenticated_userid(request) | ||
|
|
||
| if user_id and type(current_span) is StreamedSpan: | ||
| current_span._segment.set_attribute("user.id", user_id) |
There was a problem hiding this comment.
Bug: The call to authenticated_userid(request) is not wrapped in an exception handler, which can crash the view handler if the authentication policy raises an exception.
Severity: HIGH
Suggested Fix
Wrap the call to authenticated_userid(request) and the subsequent span attribute setting within a with capture_internal_exceptions(): block. This will prevent exceptions from the authentication policy from crashing the application, aligning with the established pattern in the integration.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: sentry_sdk/integrations/pyramid.py#L89-L94
Potential issue: In the `sentry_patched_call_view` function, the call to
`authenticated_userid(request)` is not wrapped in an exception handler. Custom Pyramid
authentication policies can raise exceptions, for example, during a database failure.
Because this instrumentation runs in a critical request path, an unhandled exception
from `authenticated_userid` will propagate and crash the application's view handler.
This can occur in production when `send_default_pii` is true and span streaming is
enabled. The existing pattern in `_make_event_processor` correctly wraps this call in
`capture_internal_exceptions()` to prevent such failures.
Did we get this right? 👍 / 👎 to inform future reviews.
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.
Reviewed by Cursor Bugbot for commit cad10e8. Configure here.
| if should_send_default_pii() and has_span_streaming_enabled(client.options): | ||
| user_id = authenticated_userid(request) | ||
| if user_id: | ||
| scope.set_user({"id": user_id}) |
There was a problem hiding this comment.
Auth policy errors abort views
Medium Severity
With span streaming and send_default_pii enabled, authenticated_userid(request) runs in _call_view without capture_internal_exceptions. The Pyramid event processor wraps the same call, so an authentication policy that raises can fail the whole view before the handler runs, instead of only skipping user data on telemetry.
Reviewed by Cursor Bugbot for commit cad10e8. Configure here.
| if should_send_default_pii() and has_span_streaming_enabled(client.options): | ||
| user_id = authenticated_userid(request) | ||
| if user_id: | ||
| scope.set_user({"id": user_id}) |
There was a problem hiding this comment.
Bug: The call to scope.set_user({"id": user_id}) in the Pyramid integration overwrites any pre-existing user data on the scope, instead of merging with it.
Severity: LOW
Suggested Fix
Modify the implementation to merge with existing user data instead of overwriting it. Fetch the current user data from the scope, merge the new {"id": user_id} into it, and then call scope.set_user with the complete, merged dictionary. This follows the safer pattern seen in the Quart integration.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: sentry_sdk/integrations/pyramid.py#L92
Potential issue: In the Pyramid integration, `scope.set_user` is called with only the
user ID (`{"id": user_id}`). This action replaces the entire `_user` dictionary on the
isolation scope. If any other middleware or integration has previously set user
properties like email or username, that information will be lost. Consequently,
subsequent telemetry spans will only contain the `user.id` attribute, losing other
valuable user context. This behavior is inconsistent with other integrations, such as
Quart, which correctly merge new user data with existing properties.
Codecov Results 📊✅ 90826 passed | ⏭️ 6129 skipped | Total: 96955 | Pass Rate: 93.68% | Execution Time: 314m 53s 📊 Comparison with Base Branch
All tests are passing successfully. ✅ Patch coverage is 100.00%. Project has 2410 uncovered lines. Files with missing lines (1)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 89.84% 89.85% +0.01%
==========================================
Files 192 192 —
Lines 23740 23745 +5
Branches 8194 8198 +4
==========================================
+ Hits 21329 21335 +6
- Misses 2411 2410 -1
- Partials 1343 1343 —Generated by Codecov Action |


When span streaming is enabled and
send_default_piiis true, set theuser.idattribute on all spans usingscope.set_userusing the authenticated user ID from the Pyramid request.Fixes #6605
Fixes PY-2542