Skip to content

feat(workflow_engine): Only link workflows to the IssueStream#112276

Merged
saponifi3d merged 10 commits intomasterfrom
jcallender/aci/organize-rule-defaults
Apr 7, 2026
Merged

feat(workflow_engine): Only link workflows to the IssueStream#112276
saponifi3d merged 10 commits intomasterfrom
jcallender/aci/organize-rule-defaults

Conversation

@saponifi3d
Copy link
Copy Markdown
Contributor

@saponifi3d saponifi3d commented Apr 6, 2026

Description

Update the on project creation to only link to the issue stream detector, rather than the issue stream and error detectors.

Moves the code into workflow_engine to keep things organized.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 6, 2026
@saponifi3d saponifi3d force-pushed the jcallender/aci/organize-rule-defaults branch 2 times, most recently from 9e8cb89 to d1ae9bb Compare April 6, 2026 19:23
@saponifi3d saponifi3d force-pushed the jcallender/aci/organize-defaults-code branch from 682bf2a to 2f3a48c Compare April 6, 2026 19:24
@saponifi3d saponifi3d force-pushed the jcallender/aci/organize-rule-defaults branch from d1ae9bb to f146ca8 Compare April 6, 2026 19:24
@saponifi3d saponifi3d changed the title Jcallender/aci/organize rule defaults ref(workflow_engine): Normalize the Workflow creation for a new project Apr 6, 2026
@github-actions

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

@getsentry getsentry deleted a comment from github-actions bot Apr 6, 2026
@getsentry getsentry deleted a comment from github-actions bot Apr 6, 2026
@getsentry getsentry deleted a comment from github-actions bot Apr 6, 2026
@saponifi3d saponifi3d force-pushed the jcallender/aci/organize-rule-defaults branch from 1783511 to d5af62d Compare April 6, 2026 23:01
@github-actions

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

@saponifi3d saponifi3d requested review from a team as code owners April 7, 2026 16:43
@saponifi3d saponifi3d requested a review from kcons April 7, 2026 16:43
@saponifi3d saponifi3d force-pushed the jcallender/aci/organize-rule-defaults branch from 014e847 to 12683dc Compare April 7, 2026 17:20
if existing:
return existing

with transaction.atomic(router.db_for_write(Workflow)):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#todo - might be nice to provide a helper to create workflows in the future.

@kcons
Copy link
Copy Markdown
Member

kcons commented Apr 7, 2026

(still reviewing)

Copy link
Copy Markdown
Member

@kcons kcons left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG, but a few notes on things that confused me.

project=self.project,
defaults={"config": {}, "name": ERROR_DETECTOR_NAME},
)
AlertRuleDetector.objects.get_or_create(detector=error_detector, rule_id=self.rule.id)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still want to do this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i believe so - this code is really to setup the references on the legacy tables, and i think we'd need all these references until we are no longer dual writing in the API.

workflow=workflow,
)
for detector in default_detectors
if detector.type != ErrorGroupType.slug
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe _create_detector_lookups shouldn't return the error detector if we're not trying to associate with it?


DetectorWorkflow.objects.bulk_create(
references_to_create,
ignore_conflicts=True,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious; why?

Copy link
Copy Markdown
Contributor Author

@saponifi3d saponifi3d Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crons. Crons creates all their workflows / alerts through this layer, so there may be cases where they are already created / have the connection. if i don't ignore_conflicts there's an edge case that those cause 💥


error_detector_workflow = DetectorWorkflow.objects.get(detector=error_detector)
assert error_detector_workflow.workflow == workflow
assert not DetectorWorkflow.objects.filter(detector=error_detector).exists()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like maybe this assert method can go away, or maybe needs to be renamed?
assert_issue_stream_detector_migrated covers the issue stream presence/existence, and I'm not sure we need to verify that an error detector exists and has specific values in order to check it isn't associated.

Comment on lines +28 to +31
) -> Sequence[DetectorWorkflow]:
# Because we don't know if this signal is handled already or not...
issue_stream_detector = _ensure_detector(project, IssueStreamGroupType.slug)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: An UnableToAcquireLockApiError in ensure_default_workflows is silently swallowed by send_robust(), causing workflow creation to fail without any logging or alerts.
Severity: MEDIUM

Suggested Fix

Wrap the call to _ensure_detector within ensure_default_workflows in a try/except block. Explicitly catch the UnableToAcquireLockApiError, log a warning, and capture the exception to Sentry for visibility, similar to the pattern used in project_detectors.py.

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/workflow_engine/defaults/workflows.py#L28-L31

Potential issue: The `ensure_default_workflows` function, called via the
`project_created` signal, can raise an `UnableToAcquireLockApiError` if it fails to
acquire a lock when creating a detector. Because the signal is dispatched using
`send_robust()`, this exception is silently swallowed without any logging or error
handling. This results in a silent failure where the default workflow is not created for
the new project, and there is no visibility into the failure, making it difficult to
debug in production.

@saponifi3d saponifi3d merged commit 7a341a7 into master Apr 7, 2026
76 checks passed
@saponifi3d saponifi3d deleted the jcallender/aci/organize-rule-defaults branch April 7, 2026 23:38
saponifi3d added a commit that referenced this pull request Apr 8, 2026
# Description
Since these workflows are connected to both the Issue Stream and the
Error detector, we can remove the connection to the error detector
because it's a subset of the Issue Stream.

This PR will find where this redundant connection is occurring, and
remove the relationship for the Error Detector, while preserving it.

We don't need to make any processing changes etc, because of how these
are selected in `processors/worfklow.py`

This PR should only be merged after:
#112276 so we don't add any new
connections after migrating.
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