Describe the bug
The PKCE refresh path added in #7854 only runs through API.requestFunction. With use_graphql: true, Apollo HTTP Link calls fetch directly. If the first API call after the OAuth access token expires is a GraphQL query, it fails with a 401 and the stored refresh token is never used.
GitLab documents invalid GraphQL authentication as an HTTP 401 with {"errors":[{"message":"Invalid token"}]}, while the current REST refresh path recognizes the OAuth {"error":"invalid_token"} shape.
I reproduced this on current main with a focused test. It returns a GraphQL 401 for Bearer EXPIRED_TOKEN, expects the request to refresh and retry with Bearer NEW_TOKEN, and currently fails on the first response with Network error: Response not successful: Received status code 401.
To Reproduce
- Configure the GitLab backend with PKCE and
use_graphql: true.
- Sign in and let the two-hour OAuth access token expire.
- Make a collection request that uses the GraphQL path before any REST request refreshes the token.
- The request fails with a 401 instead of refreshing.
Expected behavior
GraphQL should use the same behavior as REST: refresh the PKCE token pair, persist the rotated credentials, and retry the failed request once. Concurrent failures should continue sharing the existing refresh promise.
Screenshots
Not applicable.
Applicable Versions:
CMS configuration
backend:
name: gitlab
auth_type: pkce
app_id: your-app-id
use_graphql: true
Additional context
GitLab GraphQL authentication docs: https://docs.gitlab.com/api/graphql/#authentication
The smallest fix I see is to route Apollo HTTP Link through the backend request function and recognize GitLab GraphQL invalid-token responses there. That would keep refresh coalescing and credential persistence in one place. I can send the regression test and patch if this direction looks right.
Describe the bug
The PKCE refresh path added in #7854 only runs through
API.requestFunction. Withuse_graphql: true, Apollo HTTP Link callsfetchdirectly. If the first API call after the OAuth access token expires is a GraphQL query, it fails with a 401 and the stored refresh token is never used.GitLab documents invalid GraphQL authentication as an HTTP 401 with
{"errors":[{"message":"Invalid token"}]}, while the current REST refresh path recognizes the OAuth{"error":"invalid_token"}shape.I reproduced this on current
mainwith a focused test. It returns a GraphQL 401 forBearer EXPIRED_TOKEN, expects the request to refresh and retry withBearer NEW_TOKEN, and currently fails on the first response withNetwork error: Response not successful: Received status code 401.To Reproduce
use_graphql: true.Expected behavior
GraphQL should use the same behavior as REST: refresh the PKCE token pair, persist the rotated credentials, and retry the failed request once. Concurrent failures should continue sharing the existing refresh promise.
Screenshots
Not applicable.
Applicable Versions:
mainate50c1b16; the affected path is also present in releases containing fix(gitlab): refresh expired PKCE access tokens #7854CMS configuration
Additional context
GitLab GraphQL authentication docs: https://docs.gitlab.com/api/graphql/#authentication
The smallest fix I see is to route Apollo HTTP Link through the backend request function and recognize GitLab GraphQL invalid-token responses there. That would keep refresh coalescing and credential persistence in one place. I can send the regression test and patch if this direction looks right.