xtekky/gpt4free · error · RuntimeError
No refresh token found in credentials.
Error message
No refresh token found in credentials.
What it means
RuntimeError raised near the end of Antigravity token bootstrap: credentials WERE found, but they contain no refresh_token, and the stored access_token is either absent or already expired (checked against expiry_date with TOKEN_BUFFER_TIME headroom). Without a refresh token there is no way to mint a new access token, so the flow refuses instead of sending doomed requests.
Source
Thrown at g4f/Provider/needs_auth/Antigravity.py:437
if creds.get("project_id"):
self._project_id = creds["project_id"]
refresh_token = creds.get("refresh_token")
access_token = creds.get("access_token")
expiry_date = creds.get("expiry_date") # milliseconds since epoch
# Use original access token if still valid
if access_token and expiry_date:
expires_at = expiry_date / 1000
if expires_at - now > self.TOKEN_BUFFER_TIME:
self._access_token = access_token
self._expiry = expires_at
await self._cache_token(access_token, expiry_date)
return
# Otherwise, refresh token
if not refresh_token:
raise RuntimeError("No refresh token found in credentials.")
await self._refresh_and_cache_token(refresh_token)
async def _refresh_and_cache_token(self, refresh_token: str) -> None:
"""Refresh the OAuth token and cache it."""
headers = {"Content-Type": "application/x-www-form-urlencoded"}
data = {
"client_id": self.OAUTH_CLIENT_ID,
"client_secret": self.OAUTH_CLIENT_SECRET,
"refresh_token": refresh_token,
"grant_type": "refresh_token",
}
async with aiohttp.ClientSession() as session:
async with session.post(
self.OAUTH_REFRESH_URL, data=data, headers=headers
) as resp:
if resp.status != 200:View on GitHub (pinned to 973504e177)
Solutions
- Re-run the interactive Antigravity OAuth login to obtain fresh credentials that include a refresh_token.
- Inspect the credentials JSON/file and confirm a top-level "refresh_token" field exists (not nested or renamed).
- If building the service-account JSON manually, include the full OAuth payload: refresh_token (required), plus access_token/expiry_date for a warm start.
- Delete the stale cache file so the next run cannot reuse tokenless credentials.
Example fix
# before: {"access_token":"...","expiry_date":1700000000000} -> expired, no refresh
# after: {"refresh_token":"1//0g...","access_token":"...","expiry_date":...} Defensive patterns
Strategy: validation
Validate before calling
creds = json.loads(Path(creds_path).read_text())
if not creds.get('refresh_token'):
raise SystemExit('Credentials lack refresh_token — re-run the Antigravity OAuth login') Type guard
def has_refresh_token(creds: dict) -> bool:
return isinstance(creds.get('refresh_token'), str) and bool(creds['refresh_token']) Try / catch
try:
...
except RuntimeError as e:
if 'No refresh token' in str(e):
# unrecoverable offline: only interactive re-login can fix
raise PermissionError('Re-authenticate with Antigravity to obtain a refresh token') from e
raise Prevention
- Always store the full OAuth payload including refresh_token when persisting credentials.
- Validate credential shape (refresh_token present) before entering the token-refresh path.
- Refresh tokens before expiry via _refresh_and_cache_token rather than waiting for hard failure.
When it happens
Trigger: Credentials JSON containing only an expired/missing-expiry access_token (partial export of an OAuth session); a service-account JSON of the wrong type (API-key-style JSON with no OAuth fields); users stripping the refresh_token for 'safety' before saving; cached token files from an older schema that stored tokens under different keys.
Common situations: Reusing an old cache file after the upstream auth flow changed token persistence; copying only part of the OAuth JSON into ANTIGRAVITY_SERVICE_ACCOUNT; long-lived deployments where the single access token (1h TTL) expired and no refresh token was ever stored.
Related errors
- Failed to read OAuth credentials from {path}: {e}
- OAuth error: {OAuthCallbackHandler.callback_error}
- ANTIGRAVITY_SERVICE_ACCOUNT environment variable not set. Pl
- Token refresh failed: {text}
- No access_token in refresh response.
AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14).
Data as JSON: /api/errors/5b3fa8e0ae300dad.
Report an issue: GitHub.