Error events captured with no context tell you something crashed but not who, where, or what the user was doing — making reproduction difficult and prioritization impossible. Attaching PII to error context (email addresses, full names, raw form values) violates GDPR Art. 5(1)(f) (integrity and confidentiality) and Art. 25 (data minimization by design). CWE-359 (Exposure of Private Personal Information) applies when email or identity fields are attached to error events that are stored and queryable in third-party services like Sentry. User IDs (non-identifiable UUIDs) are acceptable; email addresses are not — they link errors to identifiable individuals stored in a vendor's system.
Medium because contextless errors are a productivity failure, and PII-in-errors is a GDPR data minimization violation requiring remediation before a data subject access request exposes it.
Set user context once after authentication using only non-identifying fields, then add action context per capture.
// After user authenticates — ID only, never email or name
Sentry.setUser({ id: session.userId })
Sentry.setTag('plan', session.planTier)
For individual captures:
Sentry.withScope((scope) => {
scope.setTag('action', 'checkout.submit')
scope.setContext('cart', { itemCount: cart.items.length }) // aggregate, not raw items
Sentry.captureException(error)
})
Audit your existing Sentry user context configuration and remove any fields containing email, name, or other GDPR-covered PII.
ID: saas-error-handling.error-reporting.errors-include-context-no-pii
Severity: medium
What to look for: Examine error reporting initialization and error capture calls. Look for: (1) whether user context is attached (Sentry's setUser(), Bugsnag's setUser(), or custom tags with user ID, session ID, or role); (2) whether route/page context is attached (URL, route params, feature area); (3) whether action context is attached (what the user was doing when the error occurred); (4) critically, whether any of this context includes PII — full names, email addresses, phone numbers, passwords, or raw user input. User IDs (non-identifiable UUIDs or numeric IDs) are acceptable; email addresses are not.
Pass criteria: Count all captureException or equivalent error reporting calls in the codebase. Pass if errors are captured with at least 1 contextual field (user ID, route, or action label) and none of the captured fields contain email addresses, full names, or other PII. A bare captureException(error) with no context is a fail; a captureException(error) with { userId: session.userId, route: pathname } is a pass. Report the count: "X of Y error capture calls include contextual fields."
Fail criteria: Fail if errors are captured with no context at all (pure captureException(error) calls everywhere). Fail if context includes PII fields (email, name, phone, raw form values). Fail if user data is passed directly from form state into error context without filtering.
Skip (N/A) when: No error reporting service is configured (the error-reporting-service check already surfaces this). Skip this check if that check resulted in fail or skip.
Detail on fail: Describe what context is missing or what PII was found (e.g., "captureException called without user/route context in 8 locations" or "Sentry setUser() includes email field — replace with userId only"). Max 500 chars.
Remediation: Errors without context are debugging nightmares — you see what crashed but not who, where, or when. Errors with too much context create privacy liability.
Set up context once at the session level:
// After user authenticates
Sentry.setUser({ id: session.userId }) // ID only, never email or name
Sentry.setTag('plan', session.planTier)
For individual error captures, add action context:
Sentry.withScope((scope) => {
scope.setTag('action', 'checkout.submit')
scope.setContext('cart', { itemCount: cart.items.length }) // aggregate data, not raw items
Sentry.captureException(error)
})
Review your Sentry/Bugsnag user context configuration and remove any fields containing email, name, or other PII.