docs(oidc): add OIDCHandler error responses table and fix HTTP status note#69
Conversation
…note OIDCHandler was the only handler section in the README without a structured '#### Error responses' table. Every other handler (AuthHandler, APIKeyHandler, SessionHandler, PasskeyHandler, TOTPHandler, MagicLinkHandler, EmailVerificationHandler, PasswordResetHandler) already has one. Changes: - Add '#### Error responses' table for OIDCHandler covering all four endpoints: Login (500), Callback (400/401/500), CreateLinkNonce (always 200), Link (400/401/409). All paths verified against handler/oidc.go. - Fix the existing Note blockquote that described Callback's JSON error responses as '(HTTP 401)' — the code can return 400, 401, or 500 depending on the failure point. Updated to '(HTTP 400, 401, or 500 as appropriate)'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds structured error-response documentation for OIDCHandler in the README to bring it in line with other handler sections, and corrects the note about which HTTP status codes may be returned as JSON errors during the OIDC exchange.
Changes:
- Update the existing
handleLinkCallbacknote to reflect JSON error statuses can be400,401, or500(not only401). - Add a new
#### Error responsestable forOIDCHandlercoveringLogin,Callback,CreateLinkNonce, andLink.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds OIDCHandler error responses table and corrects the HTTP-status note for early OIDC-exchange JSON errors. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 1/1 changed files
- Comments generated: 3
| | `Callback` | `400 Bad Request` | State cookie missing; state parameter mismatch; PKCE verifier cookie missing; `code` parameter absent; `sub` or `email` claim absent in the ID token | | ||
| | `Callback` | `401 Unauthorized` | Provider returned an `error` parameter; code exchange failed; `id_token` missing or invalid; email not verified | | ||
| | `Callback` | `500 Internal Server Error` | Claims parsing failed; user lookup or creation failed; JWT creation failed | | ||
| | `CreateLinkNonce` | `200 OK` | Always succeeds — no error response | |
There was a problem hiding this comment.
CreateLinkNonce is documented as “Always succeeds — no error response”, but the implementation ignores generateOIDCState() errors (nonce, _ := generateOIDCState()). On RNG failure it will still return 200 with an empty nonce, which is effectively not usable. Consider documenting this as “Always returns 200 OK (nonce generation errors are ignored)” (or alternatively, change the handler to return 500 on nonce generation failure).
| | `CreateLinkNonce` | `200 OK` | Always succeeds — no error response | | |
| | `CreateLinkNonce` | `200 OK` | Always returns 200 OK; nonce generation errors are ignored | |
| | `CreateLinkNonce` | `200 OK` | Always succeeds — no error response | | ||
| | `Link` | `400 Bad Request` | `nonce` query parameter missing | | ||
| | `Link` | `401 Unauthorized` | Nonce not found, already consumed, or expired | | ||
| | `Link` | `409 Conflict` | User not found or account is already OIDC-linked | |
There was a problem hiding this comment.
The Link 409 condition lists only “User not found or account is already OIDC-linked”, but handler/oidc.go returns 409 for any Users.FindByID error (including transient store failures), as well as when OIDCSubject != nil. Please update the condition text to include store/lookup errors (or adjust the handler to return 500 for store failures if that’s the intended behavior).
| | `Link` | `409 Conflict` | User not found or account is already OIDC-linked | | |
| | `Link` | `409 Conflict` | User lookup failed or user not found, or account is already OIDC-linked | |
|
|
||
| #### Error responses | ||
|
|
||
| All `OIDCHandler` JSON error endpoints return `{"error": "<message>"}` on failure. Redirect-path outcomes (`Callback` when a link flow is active, and all `Link`-initiated redirects) are covered by the tables above, not here. |
There was a problem hiding this comment.
This new error table clarifies that Callback can return JSON error bodies, but earlier in the same section the README states “Callback does not return JSON.” That’s misleading given writeError(...) paths in handler/oidc.go. Consider tightening the earlier wording to “Callback does not return JSON on success” (or similar) to avoid contradiction for API consumers.
| All `OIDCHandler` JSON error endpoints return `{"error": "<message>"}` on failure. Redirect-path outcomes (`Callback` when a link flow is active, and all `Link`-initiated redirects) are covered by the tables above, not here. | |
| When an `OIDCHandler` endpoint fails with a JSON response, the body is `{"error": "<message>"}`. This includes `Callback` failure paths that do not redirect. Redirect-path outcomes (`Callback` when a link flow is active, and all `Link`-initiated redirects) are covered by the tables above, not here. |
Accept origin/main's more accurate error table which adds explicit JSON/redirect labels, a CreateLinkNonce 500 row, and a Link 500 row.
Summary
OIDCHandlerwas the only handler section in the README that lacked a structured#### Error responsestable. Every other handler (AuthHandler,APIKeyHandler,SessionHandler,PasskeyHandler,TOTPHandler,MagicLinkHandler,EmailVerificationHandler,PasswordResetHandler) already has one.Two existing open PRs (#64, #67) attempted to add this table but both had accuracy issues identified by reviewers and may not apply cleanly to the current
main. This PR starts clean from the currentmainwith verified-accurate content.Changes
1. New
#### Error responsestable forOIDCHandlerAll four endpoints are documented, with every path verified against
handler/oidc.go:Login500generateOIDCState()failure;oauth2.GenerateVerifier()cannot fail — no error return)Callback400codeabsent;sub/emailclaims absentCallback401errorparam; code exchange failed;id_tokenmissing or invalid; email not verifiedCallback500CreateLinkNonce200 OKgenerateOIDCState()is silently discarded at line 249)Link400noncequery param missingLink401Link4092. Fix inaccurate HTTP status in the existing blockquote Note
The Note at the end of the
Linkredirect-outcomes section previously read:The code actually returns
400,401, and500fromCallbackdepending on the failure point. Updated to:Accuracy notes (addressing known issues in prior PRs)
generateOIDCState()is fallible;oauth2.GenerateVerifier()has no error return. The table row says "State generation failed" — not "PKCE verifier generation failed" (which was the inaccuracy in PR docs(oidc): add OIDCHandler error response table and fix Callback status code note #64).handler/oidc.go:98-102only checks whether the verifier cookie is missing; a value mismatch surfaces as401from the code exchange. The table row says "PKCE verifier cookie missing" — not "missing or mismatched" (which was the inaccuracy in PR docs: add OIDCHandler error table and Cache-Control response header notes #67).200 OKin the Status column (not*(none)*, which was confusing in PR docs: add OIDCHandler error table and Cache-Control response header notes #67).Files changed
README.mdonly (+16 lines, -1 line)Greptile Summary
This PR updates a single sentence in the
OIDCHandlerdocumentation note, correcting "HTTP 401" to "HTTP 400, 401, or 500 as appropriate" — an accurate fix sinceCallbackreturns all three status codes depending on the failure point. The error-response table described in the PR description was already merged tomainbefore this branch was rebased, so the effective diff is one line.Confidence Score: 5/5
Safe to merge — docs-only change, the corrected HTTP status range is accurate against the source code.
The one changed line is a correct factual fix verified against handler/oidc.go. No logic, security, or data-integrity issues. Remaining finding is a P2 note about misleading PR description text, which does not affect the documentation accuracy.
No files require special attention.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD CB[Callback] --> SC{State cookie\npresent?} SC -- No --> B1[400 Bad Request] SC -- Yes --> SM{State match?} SM -- No --> B2[400 Bad Request] SM -- Yes --> VC{PKCE verifier\ncookie present?} VC -- No --> B3[400 Bad Request] VC -- Yes --> EP{Provider\nerror param?} EP -- Yes --> U1[401 Unauthorized] EP -- No --> CD{code\npresent?} CD -- No --> B4[400 Bad Request] CD -- Yes --> EX{Token\nexchange OK?} EX -- No --> U2[401 Unauthorized] EX -- Yes --> IT{id_token\nvalid?} IT -- No --> U3[401 Unauthorized] IT -- Yes --> CL{Claims\nparse OK?} CL -- No --> S1[500 Internal Server Error] CL -- Yes --> SC2{sub + email\npresent?} SC2 -- No --> B5[400 Bad Request] SC2 -- Yes --> EV{Email\nverified?} EV -- No --> U4[401 Unauthorized] EV -- Yes --> UR{User\nresolution OK?} UR -- No --> S2[500 Internal Server Error] UR -- Yes --> JWT{JWT\ncreation OK?} JWT -- No --> S3[500 Internal Server Error] JWT -- Yes --> R[302 Redirect /?oidc_login=1]Prompt To Fix All With AI
Reviews (2): Last reviewed commit: "merge: resolve conflict with origin/main..." | Re-trigger Greptile