Conversation
Add test coverage for the new index_repos task including early return conditions, correct payload construction, and repo deduplication across projects. Also fix broken import path and add missing response status check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend Test FailuresFailures on
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 3 total unresolved issues (including 2 from previous reviews).
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: NoneType AttributeError when project has no preferences
- Updated the preferences lookup to default to an empty dict so projects without Seer preferences no longer raise an AttributeError.
Or push these changes by commenting:
@cursor push 11d75ba62c
Preview (11d75ba62c)
diff --git a/src/sentry/tasks/seer/context_engine_index.py b/src/sentry/tasks/seer/context_engine_index.py
--- a/src/sentry/tasks/seer/context_engine_index.py
+++ b/src/sentry/tasks/seer/context_engine_index.py
@@ -259,7 +259,7 @@
preferences_by_id = bulk_get_project_preferences(organization_id, list(project_map.keys()))
for project_id, project in project_map.items():
- existing_pref = preferences_by_id.get(str(project_id))
+ existing_pref = preferences_by_id.get(str(project_id), {})
project_pref_repos = existing_pref.get("repositories") or []
autofix_repos = get_autofix_repos_from_project_code_mappings(project_map[project_id])This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
|
|
||
| for project_id, project in project_map.items(): | ||
| existing_pref = preferences_by_id.get(str(project_id)) | ||
| project_pref_repos = existing_pref.get("repositories") or [] |
There was a problem hiding this comment.
NoneType AttributeError when project has no preferences
High Severity
preferences_by_id.get(str(project_id)) returns None when a project has no Seer preferences, then existing_pref.get("repositories") raises AttributeError: 'NoneType' object has no attribute 'get'. The bulk_get_project_preferences function returns a sparse dict — only projects with configured preferences appear as keys. Using .get(str(project_id), {}) as the default would prevent the crash.
Reviewed by Cursor Bugbot for commit 3243fdb. Configure here.
There was a problem hiding this comment.
We should skip projects that don't have preferences setup. If a project does not have preferences then customers basically can't use Seer for that project.
Backend Test FailuresFailures on
|
| key = (repo["provider"], repo["owner"], repo["name"]) | ||
| if key in org_repo_definitions: | ||
| repo_definition = org_repo_definitions[key] | ||
| repo_definition["project_ids"].append(project_id) |
There was a problem hiding this comment.
Repo languages lost during cross-project deduplication
Low Severity
When a repo already exists in org_repo_definitions, only project_ids is appended — the languages field is never backfilled. If the first project to register a repo uses seer preferences (where the repo isn't in that project's autofix code mappings), languages is set to [] via language_map.get(key, []). When a later project encounters the same repo from its autofix repos (which do have language data), the existing entry's empty languages is never updated, permanently losing that information.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit e1ab127. Configure here.
| "provider": repo["provider"], | ||
| "owner": repo["owner"], | ||
| "name": repo["name"], | ||
| "external_id": repo["external_id"], |
There was a problem hiding this comment.
Bug: The code unsafely accesses keys on a raw dictionary from an API response, which will raise a KeyError if the response is malformed or missing expected keys.
Severity: HIGH
Suggested Fix
Use the safe .get() method when accessing keys from the repo dictionary to prevent KeyError exceptions. For a more robust solution, validate the raw API response with a Pydantic model before processing the data to ensure the data structure is correct.
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/tasks/seer/context_engine_index.py#L285
Potential issue: The function `index_repos` processes repository data fetched from the
Seer API via `bulk_get_project_preferences()`. The code directly accesses dictionary
keys like `repo["external_id"]`, `repo["provider"]`, `repo["owner"]`, and `repo["name"]`
without using safe access methods like `.get()`. The API response is not validated
against a schema. If the Seer API returns a malformed response object that is missing
one of these required keys, the operation will fail with a `KeyError`. This will cause
the `index_repos` background task to crash, preventing repository indexing for the
affected organization.
| language_map: dict[tuple[str, str, str], list[str]] = {} | ||
| for autofix_repo in autofix_repos: | ||
| key = (autofix_repo["provider"], autofix_repo["owner"], autofix_repo["name"]) | ||
| language_map[key] = autofix_repo["languages"] |
There was a problem hiding this comment.
Bug: The index_repos task will crash with a KeyError if a repository configured via SEER_AUTOFIX_FORCE_USE_REPOS is missing the languages key.
Severity: MEDIUM
Suggested Fix
Use the .get() method with a default value when accessing the languages key to prevent a KeyError. Change autofix_repo["languages"] to autofix_repo.get("languages", []). This will provide a safe fallback to an empty list if the key is not present in the repository configuration.
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/tasks/seer/context_engine_index.py#L271
Potential issue: When the `SEER_AUTOFIX_FORCE_USE_REPOS` setting is used, for example in
testing or staging environments, the `index_repos` task can fail. The code iterates
through the configured repositories and directly accesses the `languages` key from each
repository dictionary. However, unlike the standard code path, the logic for this
setting does not ensure the `languages` key is present. If a repository is configured
without this key, the task will raise a `KeyError` and fail, as this exception is not
configured for retries. This will halt the repository indexing process in environments
that use this override.
|
|
||
| for project_id, project in project_map.items(): | ||
| existing_pref = preferences_by_id.get(str(project_id)) | ||
| project_pref_repos = existing_pref.get("repositories") or [] |
There was a problem hiding this comment.
We should skip projects that don't have preferences setup. If a project does not have preferences then customers basically can't use Seer for that project.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 3 total unresolved issues (including 2 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit cf5c5a4. Configure here.
| ) | ||
|
|
||
| if response.status >= 400: | ||
| raise SeerApiError("Seer request failed", response.status) |
There was a problem hiding this comment.
Missing early return when no repos are collected
Low Severity
The index_repos function makes a Seer API call even when org_repo_definitions is empty (e.g., when all projects lack preferences or have empty/None repository lists). Other similar tasks like build_service_map and index_org_project_knowledge include early returns for analogous "no data" scenarios (no nodes, no high-volume projects). Adding an early return when org_repo_definitions is empty would avoid unnecessary API calls, which can add up since this runs across many orgs.
Reviewed by Cursor Bugbot for commit cf5c5a4. Configure here.
Schedule repo indexing job for context engine. This is behind a new "experimental" feature flag so we can see how this context works out on sentry seer explorer runs. Only runs index job on Sunday because we don't want to eat into GH API quotas and interfere with code review and autofix. Depends on: getsentry/seer#5594 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>



Schedule repo indexing job for context engine. This is behind a new
"experimental" feature flag so we can see how this context works
out on sentry seer explorer runs. Only runs index
job on Sunday because we don't want to eat into GH API quotas and
interfere with code review and autofix.
Depends on: https://github.com/getsentry/seer/pull/5594