Skip to content

fix: guard against None actions in get_filtered_actions#119464

Closed
billyvg wants to merge 1 commit into
masterfrom
claude/serene-cannon-j0fcf0
Closed

fix: guard against None actions in get_filtered_actions#119464
billyvg wants to merge 1 commit into
masterfrom
claude/serene-cannon-j0fcf0

Conversation

@billyvg

@billyvg billyvg commented Jul 11, 2026

Copy link
Copy Markdown
Member

Summary

Fixes a production AttributeError (SENTRY-5RDY) in the alert-rules PUT endpoint (/api/0/organizations/{org}/alert-rules/{id}/).

Root cause

AlertRuleSerializer.triggers is declared as a bare ListField with no child serializer (line 77):

triggers = serializers.ListField(required=True)

This means DRF passes list elements through as raw Python objects with no element-level coercion. If a client sends actions: [null, {...}] in a trigger, the only validation that runs is:

if not trigger.get("actions", []):   # line 208
    raise ValidationError(...)

A list like [None, {...}] is truthy, so it passes. The None flows into validated_data, into get_filtered_actions, where is_included() then calls action.get("type") and crashes:

AttributeError: 'NoneType' object has no attribute 'get'
  File "sentry/incidents/logic.py", line 1999, in is_included
      type_slug = action.get("type")
  Local Variables:
    action = None

Fix

Adds a None guard at the top of is_included() so None entries are skipped rather than crashing. Also adds regression tests covering the None-entry case, empty actions, and missing triggers.

A follow-up should add stricter validation in AlertRuleSerializer.validate() to reject null entries inside actions with a 400 at the boundary rather than silently passing them through.

Sentry issue: https://sentry.sentry.io/issues/SENTRY-5RDY
Claude session: https://claude.ai/code/session_01RCczjnRYDg9wEnRAyF1B9k

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.

When a trigger's actions list contains None entries,
is_included() would raise AttributeError calling .get() on None.
Add an early None check to skip such entries safely.

Fixes SENTRY-5RDY

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RCczjnRYDg9wEnRAyF1B9k
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jul 11, 2026
@billyvg billyvg closed this Jul 13, 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