Skip to content

feat(iswf): Adds Issue label, org label coarse data model#114925

Draft
GabeVillalobos wants to merge 2 commits intomasterfrom
gv/issue-label-proto
Draft

feat(iswf): Adds Issue label, org label coarse data model#114925
GabeVillalobos wants to merge 2 commits intomasterfrom
gv/issue-label-proto

Conversation

@GabeVillalobos
Copy link
Copy Markdown
Member

----PROTOTYPE----

Coarse data model, service, and caching layer for issue and organization-scoped labels.

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label May 5, 2026
"""
Update an IssueLabel by id.

Invalidates the cache for the owning issue.
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.

IssueLabel.update() raises DoesNotExist on missing/deleted record

IssueLabel.objects.get(id=issue_label_id) is called without handling IssueLabel.DoesNotExist. If the label was deleted concurrently or the ID is stale/invalid (e.g., from an API request), this raises an unhandled exception that propagates as a 500. Service-layer mutation entry points should surface a graceful error so callers can return 404.

Verification

Reviewed the service module in the hunk. update, delete, update_org_label, and delete_org_label all call Model.objects.get(id=...) with no try/except and no .filter().first() guard. This matches Check 2 (Missing Record / Stale Reference) — service-layer methods consumed by API endpoints should not raise DoesNotExist uncaught. No parent endpoint validation exists since this is a generic service.

Also found at 2 additional locations
  • src/sentry/issues/services/issue_label/service.py:65-65
  • src/sentry/issues/services/issue_label/service.py:99-99

Identified by Warden sentry-backend-bugs · M4X-WM4

Comment on lines +28 to +32
"""Create a new IssueLabel and invalidate the cache for its issue."""
issue_label = IssueLabel.objects.create(
group_id=group_id,
label_id=label_id,
label_value=label_value,
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.

create() and create_org_label() do not handle unique constraint violations

IssueLabel.objects.create() and OrganizationLabel.objects.create() are called without handling IntegrityError. If unique constraints exist (likely for (group_id, label_id) on IssueLabel and (organization_id, label_name) on OrganizationLabel based on typical label data models), duplicate creation requests will raise an unhandled IntegrityError resulting in a 500. This is Check 7 (Database Constraint Violations).

Verification

Read the create() and create_org_label() methods in the hunk. Cannot confirm exact unique constraints without reading src/sentry/models/issuelabel.py and src/sentry/models/organizationlabel.py (listed as other files in PR but not provided), but label models almost universally enforce uniqueness on (scope, name). Reporting at medium confidence since the constraint definitions aren't visible — the pattern (unguarded create on a label model) is a well-known precedent for IntegrityError issues.

Identified by Warden sentry-backend-bugs · GAX-S46

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

This PR has a migration; here is the generated SQL for src/sentry/migrations/1081_add_organizationlabel_and_issuelabel.py

for 1081_add_organizationlabel_and_issuelabel in sentry

--
-- Create model OrganizationLabel
--
CREATE TABLE "sentry_organizationlabel" ("id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "label_name" varchar(255) NOT NULL, "organization_id" bigint NOT NULL);
--
-- Create model IssueLabel
--
CREATE TABLE "sentry_issuelabel" ("id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "label_value" varchar(255) NOT NULL, "group_id" bigint NOT NULL, "label_id" bigint NOT NULL);
CREATE UNIQUE INDEX CONCURRENTLY "sentry_organizationlabel_organization_id_label_na_43e8691b_uniq" ON "sentry_organizationlabel" ("organization_id", "label_name");
ALTER TABLE "sentry_organizationlabel" ADD CONSTRAINT "sentry_organizationlabel_organization_id_label_na_43e8691b_uniq" UNIQUE USING INDEX "sentry_organizationlabel_organization_id_label_na_43e8691b_uniq";
ALTER TABLE "sentry_organizationlabel" ADD CONSTRAINT "sentry_organizationl_organization_id_2c47abec_fk_sentry_or" FOREIGN KEY ("organization_id") REFERENCES "sentry_organization" ("id") DEFERRABLE INITIALLY DEFERRED NOT VALID;
ALTER TABLE "sentry_organizationlabel" VALIDATE CONSTRAINT "sentry_organizationl_organization_id_2c47abec_fk_sentry_or";
CREATE INDEX CONCURRENTLY "sentry_organizationlabel_organization_id_2c47abec" ON "sentry_organizationlabel" ("organization_id");
ALTER TABLE "sentry_issuelabel" ADD CONSTRAINT "sentry_issuelabel_group_id_396a723a_fk_sentry_groupedmessage_id" FOREIGN KEY ("group_id") REFERENCES "sentry_groupedmessage" ("id") DEFERRABLE INITIALLY DEFERRED NOT VALID;
ALTER TABLE "sentry_issuelabel" VALIDATE CONSTRAINT "sentry_issuelabel_group_id_396a723a_fk_sentry_groupedmessage_id";
ALTER TABLE "sentry_issuelabel" ADD CONSTRAINT "sentry_issuelabel_label_id_fb39a67f_fk_sentry_or" FOREIGN KEY ("label_id") REFERENCES "sentry_organizationlabel" ("id") DEFERRABLE INITIALLY DEFERRED NOT VALID;
ALTER TABLE "sentry_issuelabel" VALIDATE CONSTRAINT "sentry_issuelabel_label_id_fb39a67f_fk_sentry_or";
CREATE INDEX CONCURRENTLY "sentry_issuelabel_group_id_396a723a" ON "sentry_issuelabel" ("group_id");
CREATE INDEX CONCURRENTLY "sentry_issuelabel_label_id_fb39a67f" ON "sentry_issuelabel" ("label_id");
CREATE INDEX CONCURRENTLY "sentry_issu_group_i_0f746e_idx" ON "sentry_issuelabel" ("group_id", "label_id");

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

Backend Test Failures

Failures on e813b99 in this run:

tests/sentry/deletions/test_validate_group_related_models.py::GroupRelatedModelsCompletenessTest::test_all_group_related_models_are_registeredlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/deletions/test_validate_group_related_models.py:110: in test_all_group_related_models_are_registered
    raise AssertionError("".join(error_msg))
E   AssertionError: 
E   
E   Models with group_id foreign keys are not registered in group deletion configuration!
E   This can cause orphaned records or cascade delete timeouts.
E   
E   Unregistered models:  - sentry.IssueLabel
E   
E   To fix this, add the model to one of these in src/sentry/deletions/defaults/group.py:  1. DIRECT_GROUP_RELATED_MODELS - if it should be transferred during reprocessing  2. ADDITIONAL_GROUP_RELATED_MODELS - if it has event_id or shouldn't transfer  3. EXEMPTED_MODELS in this test - if it has special handling (with justification)
E   See comments in group.py for decision criteria.

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.

1 participant