HKUDS/DeepTutor · error · RuntimeError
GitHub Copilot token exchange returned no token.
Error message
GitHub Copilot token exchange returned no token.
What it means
After POSTing to the Copilot token-exchange endpoint, the JSON payload lacked a 'token' field, so the provider cannot authenticate subsequent API calls and raises RuntimeError.
Source
Thrown at deeptutor/services/llm/provider_core/github_copilot_provider.py:88
async with httpx.AsyncClient(
timeout=timeout, follow_redirects=True, trust_env=True
) as client:
response = await client.get(
DEFAULT_COPILOT_TOKEN_URL,
headers={
"Authorization": f"token {github_token}",
"Accept": "application/json",
"User-Agent": USER_AGENT,
"Editor-Version": EDITOR_VERSION,
"Editor-Plugin-Version": EDITOR_PLUGIN_VERSION,
},
)
response.raise_for_status()
payload = response.json()
token = payload.get("token")
if not token:
raise RuntimeError("GitHub Copilot token exchange returned no token.")
expires_at = payload.get("expires_at")
if isinstance(expires_at, (int, float)):
self._copilot_expires_at = float(expires_at)
else:
refresh_in = payload.get("refresh_in") or 1500
self._copilot_expires_at = time.time() + int(refresh_in)
self._copilot_access_token = str(token)
return self._copilot_access_token
async def _ensure_api_key(self) -> None:
now = time.time()
if self._copilot_access_token and now < self._copilot_expires_at - _EXPIRY_SKEW_SECONDS:
self.api_key = self._copilot_access_token
self._client.api_key = self._copilot_access_token
return
await self._try_existing_local_auth()
View on GitHub (pinned to 3e82f13042)
Solutions
- Log in again (`deeptutor provider login github-copilot`) to refresh the underlying GitHub token.
- Check network/proxy isn't intercepting the exchange request.
- Update DeepTutor — the exchange contract may have changed.
Defensive patterns
Strategy: retry
Try / catch
try:
resp = await provider.chat(messages)
except RuntimeError as e:
if 'token exchange' in str(e):
relogin_and_retry_once()
else:
raise Prevention
- Treat exchange anomalies as stale-auth signals and auto-trigger re-login
- Pin known-good DeepTutor versions to track Copilot API changes
- Log the exchange payload keys (never values) when debugging
When it happens
Trigger: The exchange endpoint returns 200 but a body without 'token' (or token=null/empty) — API contract change, rate limiting response, or the GitHub token being invalid such that the exchange returns an error-shaped payload with 200.
Common situations: GitHub/Copilot API changes; expired or revoked GitHub OAuth token producing a degenerate response; proxy or firewall returning an HTML interception page parsed as JSON.
Related errors
- GitHub Copilot auth is unavailable. Validate local Copilot a
- Invalid role: {role!r}. Must be 'admin' or 'user'.
- Embedding provider returned HTTP {response.status_code}
- OpenAI SDK request failed: {exc}
- OpenAI Codex is not logged in. Run `deeptutor provider login
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/3edeb74b2120e616.
Report an issue: GitHub.