Conversation
This ensures that process_autofix_updates is properly called so that the slack integration will continue to work. More work is needed to properly handle the changes but this is the starting point.
| logger.exception( | ||
| "autofix.on_completion_hook.webhook_invalid_event_type", | ||
| extra={"event_type": event_type}, | ||
| ) |
There was a problem hiding this comment.
Narrow exception handler can crash pipeline on async failures
High Severity
The except ValueError only catches enum conversion errors, but SeerOperator.has_access() and process_autofix_updates.apply_async() are also inside the same try block and can raise other exceptions (e.g., broker connection errors, database errors). In on_completion_hook.py, an uncaught exception propagates out of _send_step_webhook, which is called without a try/except in execute(), preventing _maybe_continue_pipeline and _maybe_trigger_supergroups_embedding from running — stalling the entire autofix pipeline. In autofix_agent.py, it prevents return run_id from executing.
Additional Locations (1)
| group_id = state.metadata.get("group_id") if state.metadata else None | ||
| if group_id is not None: | ||
| webhook_payload["group_id"] = group_id | ||
|
|
There was a problem hiding this comment.
Schema mismatch for Slack webhook payloads
High Severity
The Explorer autofix completion hook sends artifact data using Explorer schemas (e.g., root_cause with one_line_description, five_whys, reproduction_steps) but the Slack integration expects different schemas (description and steps with title fields). This causes the Slack integration to receive empty or incorrectly structured data, breaking the autofix updates mentioned in the PR description.
| group_id = state.metadata.get("group_id") if state.metadata else None | ||
| if group_id is not None: | ||
| webhook_payload["group_id"] = group_id | ||
|
|
There was a problem hiding this comment.
Slack integration crashes on None artifact data
High Severity
When an artifact has data=None, line 117 adds None to the webhook payload. The Slack entrypoint expects a dict and calls .get() on it (e.g., root_cause.get("description", "")). Since dict.get(key, default) returns the actual value when the key exists (even if None), not the default, this causes AttributeError: 'NoneType' object has no attribute 'get', crashing the Slack integration webhook processing.
|
|
||
| group.update(seer_autofix_last_triggered=timezone.now()) | ||
|
|
||
| # Send "started" webhook after we have the run_id |
There was a problem hiding this comment.
Missing group_id for manual runs breaks Slack integration
High Severity
When trigger_autofix_explorer is called with stopping_point=None (manual runs), group_id is not stored in metadata. The "started" webhook includes group_id directly from the group object, but "completed" webhooks from on_completion_hook try to extract group_id from metadata. When missing, process_autofix_updates receives a payload without group_id, fails the if not run_id or not group_id check, and records "missing_identifiers", breaking the Slack integration for manual autofix runs.
Additional Locations (1)
| if SeerOperator.has_access(organization=group.organization): | ||
| process_autofix_updates.apply_async( | ||
| kwargs={ | ||
| "event_type": sentry_app_event_type, | ||
| "event_payload": payload, | ||
| "organization_id": group.organization.id, | ||
| } | ||
| ) |
There was a problem hiding this comment.
Bug: The call to process_autofix_updates is gated by SeerOperator.has_access(), which intentionally returns False for explorer autofix organizations, preventing the new functionality from ever running.
Severity: HIGH
Suggested Fix
Remove the if SeerOperator.has_access(organization=group.organization): check that wraps the process_autofix_updates.apply_async() call. This check is designed for the legacy autofix system and incorrectly blocks the new explorer autofix pipeline from using this function.
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: src/sentry/seer/autofix/autofix_agent.py#L209-L216
Potential issue: The functions `trigger_autofix_explorer` and `on_completion_hook` are
intended to support the explorer autofix pipeline. They now call
`process_autofix_updates` to enable Slack integrations for this pipeline. However, this
call is gated by `SeerOperator.has_access()`, which is explicitly designed to return
`False` for any organization with the `organizations:autofix-on-explorer` feature flag
enabled. As a result, `process_autofix_updates` will never be executed for the intended
explorer autofix use case, causing the feature to fail silently for all targeted
organizations.
There was a problem hiding this comment.
This is correct but will be addressed in a future PR
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.
| "event_payload": payload, | ||
| "organization_id": group.organization.id, | ||
| } | ||
| ) |
There was a problem hiding this comment.
has_access guard blocks explorer autofix updates entirely
High Severity
SeerOperator.has_access explicitly returns False when the organizations:autofix-on-explorer feature flag is enabled (see operator.py line 84). Since trigger_autofix_explorer is only called for organizations with that flag, the process_autofix_updates.apply_async call is unreachable dead code for its intended use case. The Slack integration this PR aims to enable will never fire for explorer autofix organizations.
Additional Locations (1)
There was a problem hiding this comment.
This is correct but will be addressed in a future PR
…108389) This ensures that process_autofix_updates is properly called so that the slack integration will continue to work. More work is needed to properly handle the changes but this is the starting point.


This ensures that process_autofix_updates is properly called so that the slack integration will continue to work. More work is needed to properly handle the changes but this is the starting point.