Session resume blocks on MCP OAuth tokens that cannot be refreshed, timing out after 60s instead of failing fast
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 48/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Ambito
- authentication, desktop
Direzione di ricerca
Non sono indicati né un file sorgente né un test. Riproduci la ripresa della sessione con file scaduti privi di refreshToken in ~/.copilot/mcp-oauth-config, quindi traccia il percorso di ripresa della sessione e riconnessione MCP usando i log di timeout riportati. Il lavoro è completato quando i server non rinnovabili falliscono rapidamente o vengono segnalati come server che richiedono l'accesso, senza impedire la ripresa della sessione.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
App version
1.1.15 (Windows)
OS
Windows 11 Enterprise 10.0.26100 (build 26100), AMD64
Summary
When a cached MCP OAuth token has expired and has no refresh token, it
cannot be renewed without interactive sign-in. On session resume the app still
attempts a cached-token reconnect for each such server and waits, rather than
recognising the token as unrenewable and failing fast. With enough of these,
resume exhausts its 60s ceiling and fails.
Steps to reproduce
- Configure one or more MCP servers that authenticate via OAuth.
- Let their cached tokens expire without completing a re-auth prompt. Tokens
accumulate in~/.copilot/mcp-oauth-config/*.tokens.json; the ones that
matter have a pastexpiresAtand norefreshTokenfield. - Restart the app and resume an existing session.
Count the unrenewable tokens:
$now = Get-Date
Get-ChildItem "$env:USERPROFILE\.copilot\mcp-oauth-config" -Filter *.tokens.json |
ForEach-Object {
$j = Get-Content $_.FullName -Raw | ConvertFrom-Json
if (-not $j.expiresAt) { return }
# expiresAt is Unix seconds on Windows 1.1.15; handle ISO strings too.
$exp = if ($j.expiresAt -is [string]) { [datetime]::Parse($j.expiresAt) }
else { [DateTimeOffset]::FromUnixTimeSeconds([int64]$j.expiresAt).LocalDateTime }
if ($exp -lt $now -and -not $j.refreshToken) { $_.Name }
} | Measure-Object | Select-Object -ExpandProperty Count
Expected behavior
A token that is expired and has no refresh token is known-unrenewable before
any network call. Resume should skip it immediately (surfacing "needs sign-in"
for that server) and continue. One unreachable MCP server should not be able to
delay or fail session resume.
Actual behavior
The app attempts a cached-token reconnect per server and waits. Once enough of
them cannot answer, resume hits its ceiling and the session fails to open:
WARN session::manager::lifecycle: session resume timed out; releasing CLI and surfacing error
WARN session::manager::cli_pool: force-retiring pooled CLI process
ERROR handlers::session: extensibility RPC failed method=session.mcp.list error=request cancelled
ERROR handlers::session: failed to resume session error=operation timed out:
session resume timed out after 60s
I had 51 of 53 cached tokens expired, 45 of them with no refresh token.
Every resume of a previously working session failed at exactly 60s.
Impact — it cascades
The failure is not contained to one resume:
- Resume times out at 60s and the pooled CLI process is force-retired.
- The UI appears to hang. Windows logged
AppHangB1forgithub.exe1.1.15
twice within seven minutes, both under the same fault bucket
(1215446218445078001) — so it is reproducible, not a one-off. - The natural user response is to end the task in Task Manager, which kills
only the root process and orphans its children (see companion issue about
there being no way to fully quit the app). - The next launch starts a fresh set of child processes on top of the strays.
After a few cycles I had ~23 app-related processes holding 4.3 GB, with
free RAM down from 12 GB to 7 GB. Every new session I opened was also affected,
so the app looked broadly broken rather than "one MCP server needs sign-in".
Fix that worked
Deleting only the expired token files resolved it completely:
| before | after | |
|---|---|---|
| session resume | timed out at 60s | 6.6s – 8.2s |
| unreachable MCP server | consumed the resume budget | fails in < 1s |
| resume timeouts in log | repeated | 0 |
Same MCP servers, same config — only the dead tokens removed. That points at
the retry/wait path rather than the servers themselves.
Suggested fixes
- Fast-fail unrenewable tokens. If
expiresAtis past and there is no
refreshToken, skip the reconnect attempt entirely and mark the server as
needing sign-in. This requires no network call to determine. - Don't let MCP reconnect block resume. Resume the session first and let
MCP servers attach asynchronously, or give MCP a budget well under the
overall resume ceiling. - Surface it in the UI. "3 MCP servers need sign-in" is actionable;
a hang is not. Nothing in the UI indicated auth was the problem — I only
found it by reading the logs. - Prune or flag stale tokens. Tokens accumulated to 53 files over months
with no visible signal. Even a warning at a threshold would have prevented
this.
Workaround
Delete expired token files (valid ones are preserved):
$now = Get-Date
Get-ChildItem "$env:USERPROFILE\.copilot\mcp-oauth-config" -Filter *.tokens.json |
Where-Object {
$j = Get-Content $_.FullName -Raw | ConvertFrom-Json
if (-not $j.expiresAt) { return $false }
$exp = if ($j.expiresAt -is [string]) { [datetime]::Parse($j.expiresAt) }
else { [DateTimeOffset]::FromUnixTimeSeconds([int64]$j.expiresAt).LocalDateTime }
$exp -lt $now
} | Remove-Item
Servers you actually use will prompt to re-authenticate on next launch.
Logs
Happy to attach /collect-debug-logs output if useful.
- Lingua principale
- Nessun dato sulla lingua
- Stelle
- 2.1k
- Fork
- 157
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di github/app
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
Issue simili
-
area/auth bug comp/agent P3 platform/discord type/security
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
NousResearch/hermes-agent#117848 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
getgrav/grav-plugin-api#45 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
sisaku-security/sisakulint#647 ·
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
yunaremaia/driftcheck#246 ·
-
bug good-first-issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
yunaremaia/taintrace#110 ·