Skip to content

Commit f7f201a

Browse files
romtsnclaude
andcommitted
fix(code-mappings): Add source_root to get_or_create/update_or_create lookups
Update auto-source-code-config callers to include source_root in their lookup keys, matching the new unique constraint on (project, stack_root, source_root). Without this, these calls would raise MultipleObjectsReturned once multiple mappings share the same stack_root. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2fa0c9d commit f7f201a

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

src/sentry/issues/auto_source_code_config/code_mapping.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,12 @@ def create_code_mapping(
348348
new_code_mapping, _ = RepositoryProjectPathConfig.objects.update_or_create(
349349
project=project,
350350
stack_root=code_mapping.stacktrace_root,
351+
source_root=code_mapping.source_path,
351352
defaults={
352353
"repository": repository,
353354
"organization_id": organization.id,
354355
"integration_id": installation.model.id,
355356
"organization_integration_id": installation.org_integration.id,
356-
"source_root": code_mapping.source_path,
357357
"default_branch": code_mapping.repo.branch,
358358
# This function is called from the UI, thus, we know that the code mapping is user generated
359359
"automatically_generated": False,

src/sentry/issues/auto_source_code_config/task.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,12 +238,12 @@ def create_code_mapping(
238238
_, created = RepositoryProjectPathConfig.objects.get_or_create(
239239
project=project,
240240
stack_root=code_mapping.stacktrace_root,
241+
source_root=code_mapping.source_path,
241242
defaults={
242243
"repository": repository,
243244
"organization_integration_id": org_integration.id,
244245
"integration_id": org_integration.integration_id,
245246
"organization_id": org_integration.organization_id,
246-
"source_root": code_mapping.source_path,
247247
"default_branch": code_mapping.repo.branch,
248248
"automatically_generated": True,
249249
},

tests/sentry/issues/auto_source_code_config/test_process_event.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,11 @@ def _process_and_assert_configuration_changes(
177177
)
178178
for expected_cm in expected_new_code_mappings:
179179
code_mapping = current_code_mappings.get(
180-
project_id=self.project.id, stack_root=expected_cm["stack_root"]
180+
project_id=self.project.id,
181+
stack_root=expected_cm["stack_root"],
182+
source_root=expected_cm["source_root"],
181183
)
182184
assert code_mapping is not None
183-
assert code_mapping.source_root == expected_cm["source_root"]
184185
assert code_mapping.repository.name == expected_cm["repo_name"]
185186
else:
186187
assert current_code_mappings.count() == starting_code_mappings_count
@@ -939,13 +940,26 @@ def test_prevent_creating_duplicate_rules(self) -> None:
939940
self.project.update_option("sentry:grouping_enhancements", "stack.module:foo.bar.** +app")
940941
# Manually created code mapping
941942
self.create_repo_and_code_mapping(REPO1, "foo/bar/", "src/foo/")
942-
# We do not expect code mappings or in-app rules to be created since
943-
# the developer already created the code mapping and in-app rule
943+
# We do not expect in-app rules to be created since the developer
944+
# already created the in-app rule. A new code mapping is created
945+
# because the source_root differs (src/foo/ vs src/foo/bar/).
944946
self._process_and_assert_configuration_changes(
945947
repo_trees={REPO1: ["src/foo/bar/Baz.java"]},
946948
frames=[self.frame_from_module("foo.bar.Baz", "Baz.java")],
947949
platform=self.platform,
950+
expected_new_code_mappings=[
951+
self.code_mapping(stack_root="foo/bar/", source_root="src/foo/bar/"),
952+
],
948953
)
954+
# Both mappings should coexist: the manual one and the auto-created one
955+
mappings = RepositoryProjectPathConfig.objects.filter(
956+
project=self.project, stack_root="foo/bar/"
957+
)
958+
assert mappings.count() == 2
959+
assert set(mappings.values_list("source_root", flat=True)) == {
960+
"src/foo/",
961+
"src/foo/bar/",
962+
}
949963

950964
def test_basic_case(self) -> None:
951965
repo_trees = {REPO1: ["src/com/example/foo/Bar.kt"]}

0 commit comments

Comments
 (0)