Skip to content

Fix PKCE auth_session duplicate key error (SQLSTATE 23505) - #6

Merged
cursor[bot] merged 1 commit into
mainfrom
cursor/fix-pkce-auth-session-duplicate-f08f
Sep 18, 2026
Merged

cursor[bot] merged 1 commit into
mainfrom
cursor/fix-pkce-auth-session-duplicate-f08f

Conversation

@demdxx

@demdxx demdxx commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Problem

After CreateAuthorizeCodeSession, CreatePKCERequestSession was attempting to INSERT a new row using the same AuthorizeCodeSignature as the access_token, causing a unique constraint violation:

SQLSTATE 23505 on idx_auth_session_uniq_access_token_id

This bug was confirmed in Affyard production. Fosite calls both methods with the same code signature, but the previous implementation tried to INSERT twice, violating the UNIQUE(access_token) constraint.

Solution

Modified CreatePKCERequestSession to UPDATE the existing authorize code session instead of INSERTing a duplicate:

  1. Looks up the existing session by access_token (the authorize code signature)
  2. Merges PKCE parameters (code_challenge, code_challenge_method) into the existing form data
  3. Updates the row with the merged form
  4. Only INSERTs a new row if none exists (edge case)

Changes

  • pkg/auth/oauth2/serverprovider/storage.go: Rewrote CreatePKCERequestSession to use UPDATE instead of INSERT
  • pkg/auth/oauth2/serverprovider/storage_test.go: Updated test to use the same code signature for both calls, matching production behavior

Testing

✅ All existing tests pass
✅ New test validates UPDATE behavior with same code signature
✅ OAuth2PKCEFactory confirmed in correct position (after OAuth2AuthorizeExplicitFactory)
✅ All tests pass locally: go test ./... -v → PASS

CI Status

⚠️ Note: CI is failing due to a pre-existing repository configuration issue (not related to this PR):

  • go.mod requires Go 1.26.0
  • .github/workflows/tests.yml uses Go 1.25.x
  • This mismatch affects all recent commits on main branch
  • Lint check passed ✅
  • All tests pass locally ✅

See main branch recent runs: all failing with same version mismatch issue.

Notes

  • Keeps UNIQUE(access_token) constraint intact
  • Minimal diff, no changes to affyard.mono required
  • Ready for review and merge once CI configuration is updated
Open in Web Open in Cursor 

After CreateAuthorizeCodeSession, CreatePKCERequestSession was
trying to INSERT a new row with the same access_token, violating
the UNIQUE constraint idx_auth_session_uniq_access_token_id.

Fixed by updating the existing row instead of inserting a duplicate:
- CreatePKCERequestSession now looks up the existing session by access_token
- Merges PKCE data (code_challenge, code_challenge_method) into the form
- Updates the existing row instead of INSERT
- Only INSERTs if no row exists (edge case)

Updated test to use the same code signature for both calls,
matching production behavior and verifying the UPDATE logic.

Co-authored-by: Dmitry <demdxx@gmail.com>
@cursor
cursor Bot marked this pull request as ready for review September 18, 2026 06:44
@cursor
cursor Bot merged commit 038df40 into main Sep 18, 2026
3 of 6 checks passed
@cursor
cursor Bot deleted the cursor/fix-pkce-auth-session-duplicate-f08f branch September 18, 2026 06:45
demdxx added a commit that referenced this pull request Sep 18, 2026
During authorization_code grant flow, CreateAccessTokenSession was
INSERTing a new row with the same request_id from the authorize step,
violating the UNIQUE constraint idx_auth_session_uniq_request_id.

Root cause: Fosite reuses the same request.GetID() across the authorize
and token exchange steps, so both CreateAuthorizeCodeSession and
CreateAccessTokenSession were trying to create separate rows with the
same request_id.

Fix: CreateAccessTokenSession now:
1. Looks up the existing session by request_id (from authorize step)
2. Updates it with the new access token signature and session data
3. Only INSERTs if no existing session is found (edge case)

This matches the approach used in CreatePKCERequestSession (PR #6) and
aligns with how fosite manages OAuth sessions - a single session row
evolves through the authorize → token exchange lifecycle.

Added TestAuthorizationCodeToAccessTokenFlow to verify the full flow:
CreateAuthorizeCodeSession → CreateAccessTokenSession correctly updates
the existing session instead of creating a duplicate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants