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

  1. Re-run the interactive Antigravity OAuth login to obtain fresh credentials that include a refresh_token.
  2. Inspect the credentials JSON/file and confirm a top-level "refresh_token" field exists (not nested or renamed).
  3. If building the service-account JSON manually, include the full OAuth payload: refresh_token (required), plus access_token/expiry_date for a warm start.
  4. 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

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


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/5b3fa8e0ae300dad. Report an issue: GitHub.