fix(#827): recover from 422 when config.yaml repos no longer exist - #857
fix(#827): recover from 422 when config.yaml repos no longer exist#857fullsend-ai-coder[bot] wants to merge 2 commits into
Conversation
When repos listed in config.yaml are deleted, transferred, or renamed,
GitHub's POST /app/installations/{id}/access_tokens rejects the entire
batch with 422. This blocks all repos from being reconciled — even the
valid ones.
Add a retry-on-422 recovery path to mintToken:
1. If CreateInstallationToken returns 422, validate each repo
individually via GET /repos/{org}/{repo}/installation.
2. Filter to only accessible repos and retry the token request.
3. Surface dropped repos in the response (dropped_repos field) so
callers can log and alert on stale config entries.
4. If repos[0] itself is deleted (FindInstallation returns 404), fall
back to FindOrgInstallation to obtain the installation ID.
5. If all repos are inaccessible, return a clear 422 error instead of
an empty-scope token.
Security-relevant errors (e.g. cross-org installation mismatch) are
not affected — only 404 triggers the org-level fallback.
TokenCreationError is introduced as a typed error carrying the HTTP
status code, allowing callers to distinguish recoverable 422 from
other failures.
Closes #827
|
🤖 Finished Review · ✅ Success · Started 9:06 AM UTC · Completed 9:18 AM UTC |
ReviewFindingsLow
Labels: PR fixes a bug in the mint token service's handling of stale repos Previous runReviewFindingsMedium
Low
|
|
/fs-fix |
|
🤖 Finished Fix · ✅ Success · Started 10:31 AM UTC · Completed 10:39 AM UTC |
…eationError Replace fragile strings.Contains(err.Error(), "status 404") check in the FindInstallation 404 fallback with a typed installationLookupError and errors.As, mirroring the TokenCreationError pattern for consistency. Unexport TokenCreationError to tokenCreationError since it is only consumed within the mintcore package, consistent with the mintError convention. Addresses review feedback on #857
🔧 Fix agent — iteration 1 (human-triggered)Addressed 2 of 6 review findings with code fixes. Introduced installationLookupError typed error for FindInstallation to replace fragile string matching (pattern-violation). Unexported TokenCreationError to tokenCreationError for naming consistency (naming-convention). The remaining 4 findings were awareness notes or process concerns with no code changes requested. Fixed (2):
Disagreed (4):
Tests: passedNext steps:
|
|
🤖 Finished Review · ✅ Success · Started 10:41 AM UTC · Completed 10:54 AM UTC |
|
This pull request has been automatically marked as stale because it has not had any activity in the last month. It will be closed in 2 weeks if no further activity occurs. Remove the |
Summary
When repos in
config.yamlare deleted, transferred, or renamed from the org, the mint service's bulk installation-token request fails entirely — GitHub'sPOST /app/installations/{id}/access_tokensrejects the batch with 422 when any single repo name is invalid. This PR adds a retry-on-422 recovery path that validates each repo individually, filters out inaccessible ones, and retries the token request with only valid repos.Changes
internal/mintcore/github.go: AddTokenCreationErrortyped error with HTTP status code; addValidateRepoAccessfunction to check each repo viaGET /repos/{org}/{repo}/installation; addDroppedReposfield toGrantedScopeinternal/mintcore/handler.go: Add 422 retry logic inmintToken— on 422, validate repos individually, drop inaccessible ones, retry with valid subset; fall back toFindOrgInstallationwhenrepos[0]is deleted (404 only — security errors propagate); adddropped_reposto mint responseinternal/dispatch/gcf/mintsrc/mintcore/Key design decisions
Testing
TestHandler_StaleRepo422Recovery: mixed valid/invalid/disabled repos → token minted for valid+disabled, deleted repo reported as droppedTestHandler_StaleRepo422Recovery_AllInvalid: all repos gone → clear 422 errorTestHandler_AllReposValid_NoRetry: happy path → single attempt, no retry overheadTestHandler_StaleFirstRepo_FallbackToOrgInstallation: repos[0] deleted → org-level installation fallback → successful recoveryTestValidateRepoAccess*: unit tests for the validation functionTestCreateInstallationToken_Returns422AsTokenCreationError: typed error verificationTestHandler_CrossOrgInstallationMismatchsecurity check)Closes #827
Post-script verification
agent/827-mint-stale-repo-recovery)c887fc47c59d8b87b5282ca44044d2933d30df41..HEAD)