chrome-webstore-upload "invalid_grant" / bad refresh token in CI
chrome-webstore-upload exchanges your client id, client secret, and refresh token for a short-lived access token. "invalid_grant" means Google rejected that exchange, so no upload can proceed.
What this error means
The upload step fails during token exchange with "invalid_grant" or "Token has been expired or revoked", before any package is sent.
chrome-webstore-upload
Error: invalid_grant
{
"error": "invalid_grant",
"error_description": "Token has been expired or revoked."
}Common causes
The refresh token expired or was revoked
Refresh tokens for testing-mode OAuth clients expire, and changing the client or scopes invalidates an old token.
Client id/secret do not match the token
The refresh token was minted for a different OAuth client than the one configured in CI, so the grant is invalid.
How to fix it
Mint a fresh refresh token
- Re-run the OAuth consent flow for your Web Store API client to get a new refresh token.
- Update the CI secret with the new token and matching client id/secret.
- Publish the OAuth client (out of testing mode) so the token does not expire.
.github/workflows/ci.yml
env:
CLIENT_ID: ${{ secrets.WEBSTORE_CLIENT_ID }}
CLIENT_SECRET: ${{ secrets.WEBSTORE_CLIENT_SECRET }}
REFRESH_TOKEN: ${{ secrets.WEBSTORE_REFRESH_TOKEN }}Keep id, secret, and token from one client
Regenerate all three together so the refresh token always matches the client that issued it.
Terminal
chrome-webstore-upload upload --source dist.zip --extension-id "$EXT_ID"How to prevent it
- Use a published (not testing-mode) OAuth client so tokens persist.
- Store client id, secret, and refresh token together as a matched set.
- Rotate and re-mint the token before it expires.
Related guides
chrome-webstore-upload "ITEM_NOT_UPDATABLE" in CIFix Chrome Web Store "ITEM_NOT_UPDATABLE" in CI - the item is in a state (in review, or recently published) t…
chrome-webstore-upload "version ... must be greater" in CIFix Chrome Web Store "The product version ... must be greater than the previously uploaded version" in CI - t…
web-ext sign WebExtError 401 / bad API credentials in CIFix web-ext sign 401 errors in CI - the AMO API rejected your JWT issuer/secret, so the request to sign the a…