Skip to content

fix(integrations): record 409 empty repo responses as halts instead of failures#109134

Merged
trevor-e merged 5 commits intomasterfrom
telkins/expect-409-response
Feb 23, 2026
Merged

fix(integrations): record 409 empty repo responses as halts instead of failures#109134
trevor-e merged 5 commits intomasterfrom
telkins/expect-409-response

Conversation

@trevor-e
Copy link
Member

Wraps get_tree and get_repositories_from_github in SCMIntegrationInteractionEvent
context managers to track these GitHub API interactions.

Additionally, handles 409 responses from GitHub's tree API (returned for
empty repositories) as halts rather than failures. These are expected
responses that don't indicate a bug, but the SCMIntegrationInteractionEvent
wrapper was surfacing them as Sentry issues via capture_exception, which
caused high-occurrence alerts that blocked deployments.

The fix catches ApiConflictError (409) and calls record_halt() on the
lifecycle, which logs the event without creating a Sentry issue. The
exception is still re-raised so the existing circuit breaker logic in
_populate_trees continues to work as before.

Refs SENTRY-5K7F

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Feb 23, 2026
@trevor-e trevor-e marked this pull request as ready for review February 23, 2026 20:34
@trevor-e trevor-e requested a review from a team as a code owner February 23, 2026 20:34
@trevor-e trevor-e merged commit 1ce9c9e into master Feb 23, 2026
82 checks passed
@trevor-e trevor-e deleted the telkins/expect-409-response branch February 23, 2026 20:51
trevor-e added a commit that referenced this pull request Feb 24, 2026
…I calls (#109153)

Cache the result when GitHub's Git Trees API returns a 409 ("Git
Repository
is empty") instead of re-fetching on every task run.

Previously, when `get_tree` hit a 409 for an empty repo, the exception
propagated without writing to cache. This meant every subsequent
`auto_source_code_config` task run would re-fetch the same empty repos,
wasting API calls and contributing to GitHub rate limiting. For large
orgs
with many empty repos, this adds up to thousands of unnecessary API
calls
per day.

Now we catch `ApiConflictError` in `get_cached_repo_files`, cache an
empty
list with the same TTL as successful results (24h + staggered offset),
and
return early. The existing error handling in `_populate_trees` is
unaffected
since the exception no longer propagates.

Pairs with #109134 which records these 409s as halts instead of failures
in the interaction event lifecycle.

Refs SENTRY-5K7F
mchen-sentry pushed a commit that referenced this pull request Feb 24, 2026
…f failures (#109134)

Wraps `get_tree` and `get_repositories_from_github` in
`SCMIntegrationInteractionEvent`
context managers to track these GitHub API interactions.

Additionally, handles 409 responses from GitHub's tree API (returned for
empty repositories) as halts rather than failures. These are expected
responses that don't indicate a bug, but the
`SCMIntegrationInteractionEvent`
wrapper was surfacing them as Sentry issues via `capture_exception`,
which
caused high-occurrence alerts that blocked deployments.

The fix catches `ApiConflictError` (409) and calls `record_halt()` on
the
lifecycle, which logs the event without creating a Sentry issue. The
exception is still re-raised so the existing circuit breaker logic in
`_populate_trees` continues to work as before.

Refs SENTRY-5K7F
mchen-sentry pushed a commit that referenced this pull request Feb 24, 2026
…I calls (#109153)

Cache the result when GitHub's Git Trees API returns a 409 ("Git
Repository
is empty") instead of re-fetching on every task run.

Previously, when `get_tree` hit a 409 for an empty repo, the exception
propagated without writing to cache. This meant every subsequent
`auto_source_code_config` task run would re-fetch the same empty repos,
wasting API calls and contributing to GitHub rate limiting. For large
orgs
with many empty repos, this adds up to thousands of unnecessary API
calls
per day.

Now we catch `ApiConflictError` in `get_cached_repo_files`, cache an
empty
list with the same TTL as successful results (24h + staggered offset),
and
return early. The existing error handling in `_populate_trees` is
unaffected
since the exception no longer propagates.

Pairs with #109134 which records these 409s as halts instead of failures
in the interaction event lifecycle.

Refs SENTRY-5K7F
wedamija pushed a commit that referenced this pull request Feb 24, 2026
…f failures (#109134)

Wraps `get_tree` and `get_repositories_from_github` in
`SCMIntegrationInteractionEvent`
context managers to track these GitHub API interactions.

Additionally, handles 409 responses from GitHub's tree API (returned for
empty repositories) as halts rather than failures. These are expected
responses that don't indicate a bug, but the
`SCMIntegrationInteractionEvent`
wrapper was surfacing them as Sentry issues via `capture_exception`,
which
caused high-occurrence alerts that blocked deployments.

The fix catches `ApiConflictError` (409) and calls `record_halt()` on
the
lifecycle, which logs the event without creating a Sentry issue. The
exception is still re-raised so the existing circuit breaker logic in
`_populate_trees` continues to work as before.

Refs SENTRY-5K7F
wedamija pushed a commit that referenced this pull request Feb 24, 2026
…I calls (#109153)

Cache the result when GitHub's Git Trees API returns a 409 ("Git
Repository
is empty") instead of re-fetching on every task run.

Previously, when `get_tree` hit a 409 for an empty repo, the exception
propagated without writing to cache. This meant every subsequent
`auto_source_code_config` task run would re-fetch the same empty repos,
wasting API calls and contributing to GitHub rate limiting. For large
orgs
with many empty repos, this adds up to thousands of unnecessary API
calls
per day.

Now we catch `ApiConflictError` in `get_cached_repo_files`, cache an
empty
list with the same TTL as successful results (24h + staggered offset),
and
return early. The existing error handling in `_populate_trees` is
unaffected
since the exception no longer propagates.

Pairs with #109134 which records these 409s as halts instead of failures
in the interaction event lifecycle.

Refs SENTRY-5K7F
@github-actions github-actions bot locked and limited conversation to collaborators Mar 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

claude-code-assisted 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