OAuth2 Link: return 404 for missing user; keep 409 for already-linked accounts#232
Merged
Merged
Conversation
Copilot created this pull request from a session on behalf of
veverkap
May 10, 2026 18:22
View session
Contributor
There was a problem hiding this comment.
Pull request overview
Adjusts OAuth2 account-linking error semantics so a link nonce that resolves to a missing/deleted user yields a 404 user not found, while preserving 409 cannot link account strictly for the already-linked condition. This makes the OAuth2 link flow’s status codes more precise for clients.
Changes:
- Updated
OAuth2Handler.Linkto return404onUsers.FindByID(...)=auth.ErrNotFound. - Updated
TestOAuth2Link_userNotFoundto assert404instead of409.
Show a summary per file
| File | Description |
|---|---|
| handler/oauth2.go | Returns 404 user not found when the nonce maps to a missing user during OAuth2 linking. |
| handler/oauth2_test.go | Updates the link-path unit test to lock in the new 404 behavior. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 0
When FindByID returns ErrNotFound during the OIDC link flow, return 404 instead of the misleading 409 Conflict. Mirrors the same fix already applied to the OAuth2 link handler.
Contributor
|
Fixed in f596031. The OIDC link handler (handler/oidc.go:259) now returns 404 with "user not found" when FindByID returns ErrNotFound, matching the OAuth2 handler behavior. TestOIDCLink_userNotFound updated to assert StatusNotFound instead of StatusConflict. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug Fix
What was the bug?
OAuth2Handler.Link()treatedUsers.FindByID(...)=ErrNotFoundas409 cannot link account, mirroring OIDC behavior. This conflated a missing-user condition with the distinct conflict case (u.OIDCSubject != nil).How did you fix it?
/handler/oauth2.golink flow soErrNotFoundfromFindByIDreturns404 user not found.409 cannot link accountonly for the explicit already-linked branch (u.OIDCSubject != nil).TestOAuth2Link_userNotFoundin/handler/oauth2_test.goto assert404instead of409.Testing
Greptile Summary
This PR fixes a status-code conflation bug in both the OAuth2 and OIDC
Linkhandlers, where a missing user (ErrNotFoundfromFindByID) was incorrectly reported as409 Conflictinstead of404 Not Found. The409path is now reserved exclusively for the already-linked case (u.OIDCSubject != nil).handler/oauth2.go/handler/oidc.go:ErrNotFoundnow writes404 user not found;409 cannot link accountis only emitted when the user record has an existing OIDC subject.handler/oauth2_test.go/handler/oidc_test.go:userNotFoundtest cases updated to asserthttp.StatusNotFound, locking in the corrected semantics for both handlers.Confidence Score: 5/5
Safe to merge — both handlers now return the correct status codes, return paths are in place, and tests cover the corrected behavior.
The change is a minimal two-line fix applied symmetrically to both Link handlers. The logic is straightforward: a previously-incorrect status code for a missing user is now 404, and the 409 path remains correctly guarded by the explicit already-linked check. Both fixes are covered by updated unit tests. No other code paths are affected.
No files require special attention.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Link request received] --> B[Consume link nonce] B -->|nonce invalid/expired| C[401 Unauthorized] B -->|nonce error| D[500 Internal Server Error] B -->|ok| E[FindByID userID] E -->|ErrNotFound| F[404 user not found ✅ FIXED] E -->|other error| G[500 Internal Server Error] E -->|user found| H{u.OIDCSubject != nil?} H -->|yes| I[409 cannot link account] H -->|no| J[Generate state & verifier] J --> K[Redirect to OAuth2/OIDC provider]Comments Outside Diff (1)
handler/oidc.go, line 258-259 (link)handler/oidc.gohas exactly the same bug this PR fixes inoauth2.go: whenFindByIDreturnsErrNotFound, line 259 responds with409 Conflict("cannot link account") instead of404 Not Found. Callers of the OIDC link endpoint will still receive a misleading conflict error for a user that simply doesn't exist, while the OAuth2 path now returns the correct 404. The fix and the corresponding test update inoidc_test.go(parallel toTestOAuth2Link_userNotFound) appear to have been left out of this PR.Prompt To Fix With AI
Reviews (2): Last reviewed commit: "Fix OIDC link handler returning 409 for ..." | Re-trigger Greptile