Skip to content

fix: handle missing span description and non-dict MSTeams error JSON#119470

Draft
billyvg wants to merge 2 commits into
mainfrom
claude/serene-cannon-frq5jl
Draft

fix: handle missing span description and non-dict MSTeams error JSON#119470
billyvg wants to merge 2 commits into
mainfrom
claude/serene-cannon-frq5jl

Conversation

@billyvg

@billyvg billyvg commented Jul 12, 2026

Copy link
Copy Markdown
Member

Fixes two bugs surfaced by Sentry alert monitoring.


Fix 1: KeyError 'description' in N+1 DB span detector (SENTRY-5QVD — HIGH actionability)

Issue: SENTRY-5QVD — 291K+ occurrences since 2026-06-25.

Root cause: mn_plus_one_db_span_detector.py:258 did a direct dict lookup db_span["description"]. Spans arriving from the process-segments consumer can omit the "description" field, causing a KeyError. This exception is caught by the outer try/except in detect_performance_problems() which logs "Failed to detect performance problems" and suppresses detection entirely for affected spans.

Evidence from event stacktrace:

File "sentry/issue_detection/detectors/mn_plus_one_db_span_detector.py", line 258, in _maybe_performance_problem
    desc=db_span["description"],
KeyError: 'description'

Local variable common_parent_span showed "downsampled_retention_days":"30" and no "description" key.

Fix: Use db_span.get("description", "") — matches the pattern used in evidence_data throughout the same function.


Fix 2: AttributeError on non-dict MSTeams error JSON (SENTRY-5PKQ — MEDIUM)

Issue: SENTRY-5PKQ — 2573 occurrences, 240 users affected since 2026-05-11.

Root cause: msteams/metrics.py:34 called error.json.get(...) without verifying error.json is a dict. When Microsoft's OAuth endpoint returns a 401 with certain error payloads (e.g. AADSTS7000222 — expired client secret), error.json is a string, not a dict. .get() on a string raises AttributeError, which bubbles up as a noisy secondary exception obscuring the real ApiUnauthorized error.

Evidence from event stacktrace:

File "sentry/integrations/msteams/metrics.py", line 34, in translate_msteams_api_error
    if error.json.get("error", {}).get("code") in MSTEAMS_HALT_ERROR_CODES:
AttributeError: 'str' object has no attribute 'get'

The underlying cause was an expired Azure app client secret (the primary operator issue), but the secondary AttributeError was generating an additional 2500+ Sentry events.

Fix: Use isinstance(error.json, dict) instead of a truthiness check, so non-dict payloads fall through to the existing IntegrationError branch cleanly.


Session

Generated by Claude Code: https://claude.ai/code/session_01KTwqnL4x74X2LSUoHg32sd

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.


Generated by Claude Code

claude added 2 commits July 12, 2026 07:00
…tector

Spans from the process-segments consumer can arrive without a "description"
field. The detector was doing a direct dict lookup which raised KeyError and
swallowed the detection entirely (caught by the outer try/except that logs
"Failed to detect performance problems"). Use .get() with an empty-string
default so detection continues even for spans that omit the field.

Fixes SENTRY-5QVD

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KTwqnL4x74X2LSUoHg32sd
When MSTeams auth fails (e.g. expired OAuth credentials), the error response
body can be a JSON string rather than a dict. Calling .get() on a str raises
AttributeError, producing a secondary noisy exception that obscures the real
IntegrationError. Use isinstance(error.json, dict) so non-dict payloads
fall through to the existing IntegrationError branch cleanly.

Fixes SENTRY-5PKQ

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KTwqnL4x74X2LSUoHg32sd
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants