github / github/copilot-cli

Failed compaction is retried unchanged on every turn: unbounded billed retries, monotonic context growth, no user-visible error

Aperta
#4,663 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

area:context-memory area:models
Lingua principale
Shell
Stelle
11.2k
Fork
1.9k
Merge medio
14h 16m
PR unite (30g)
6

Descrizione

Describe the bug

When a compaction model call fails, the CLI reissues the identical request on essentially every subsequent turn, with no backoff, no fallback, and no reconciliation of the payload that caused the failure. Each retry is a full billed model call, and because nothing is ever reclaimed, currentTokens grows monotonically until the session hits the hard context limit.

The failure is silent. Nothing appears in the transcript; success: false is only visible in session-state/<id>/events.jsonl. From the user's side the session simply "keeps compacting" and burns credits.

This is error-agnostic and therefore outlives any individual compaction bug. I hit it via a deferred-tool 400 on 1.0.81 (see below), which no longer reproduces on 1.0.82, but the retry behaviour itself is unchanged and still applies to the open compaction-400 reports #4519 and #4572.

Evidence

Two sessions on 1.0.81-3, from local events.jsonl:

session compaction_start success failed
A 38 0 38
B 16 0 16

Every attempt returned the same error and the same toolDefinitionsTokens. Context across session A's retries, from session.compaction_start.data:

trigger=threshold  currentTokens=750,933  ->  908,833   (tokenLimit 936,000)

38 consecutive billed calls, 0 tokens reclaimed, ~158k tokens of growth. The client never varied the request between attempts.

The originating error (for context)
compaction model call failed: HostRethrow {
  message: "400 Tool reference '<redacted-mcp-tool>' not found in available tools"
}

The conversation history referenced an MCP tool that was not declared in the tools array sent with the compaction request. This occurred only while tool search / MCP tool deferral was active (toolDefinitionsTokens ~17.5k vs ~74k with the full catalogue).

The 400 itself no longer reproduces on 1.0.82. I ran 8 trials that each matched the failing shape exactly (deferral active, a deferred MCP tool present in history, automatic trigger: threshold compaction at ~160,800/200,000 tokens, toolDefinitionsTokens: 13,347); all 8 compacted successfully. Seven used one MCP server's tool; the eighth used the specific tool named in every original failure. Deferral was forced with toolSearch: true since the server-side flight is not under my control.

This report is about the retry behaviour, not that 400. The retry path is unchanged, and the same unbounded billed retry would follow from any other compaction failure.

Steps to reproduce

Any persistent compaction failure reproduces the retry loop. On 1.0.81-3:

  1. Run a session with an MCP server whose tools are deferred.
  2. Surface and call a deferred MCP tool.
  3. Let the session grow until trigger: threshold compaction fires.
  4. Observe session.compaction_complete with success: false, then the same request reissued on nearly every following turn.

Detect it in any session with:

python3 - <<'PY'
import json,glob,os
for p in glob.glob(os.path.expanduser('~/.copilot/session-state/*/events.jsonl')):
    bad=ok=0
    for line in open(p,encoding='utf-8',errors='replace'):
        if 'compaction_complete' not in line: continue
        try: e=json.loads(line)
        except: continue
        if e.get('type')!='session.compaction_complete': continue
        d=e.get('data') or {}
        if d.get('success') is False: bad+=1
        elif d.get('success') is True: ok+=1
    if bad: print(f"{p.split('/')[-2]} failed={bad} ok={ok}")
PY

Note the type check matters: tool.execution_complete and session.task_complete also carry success: true and appear on lines containing the string compaction_complete, which inflates the success count if you match the raw line.

Expected behavior

A failed compaction should not be retried unchanged and unbounded. Suggested, in order of value:

  1. Back off. Exponential backoff with a cap, and stop retrying after N consecutive identical failures.
  2. Surface it. A visible warning that compaction is failing and why. Today the only signal is credit burn.
  3. Reconcile or fall back. If the payload is structurally rejected, either repair it (for the case above: build tools from the union of the current catalogue and every tool referenced in the history being summarised) or fall back to hard truncation so the session can still reclaim context.

(3) is bug-specific; (1) and (2) are worth having regardless, and would have converted this from an invisible, unrecoverable credit drain into an actionable message.

Workaround

Resuming the session (copilot --resume=<id>) loads the full tool catalogue and lets compaction succeed. Both sessions above recovered this way, reclaiming 471,261 and 567,747 tokens. They were not permanently lost, but nothing in the UI suggests this.

Affected version
GitHub Copilot CLI 1.0.81-3 (retry loop observed)
GitHub Copilot CLI 1.0.82  (originating 400 no longer reproduces; retry path unchanged)
macOS darwin-arm64, model claude-opus-5, contextTier long_context
Related
  • #4519 and #4572 are open compaction/deferred-tool 400s that would still trigger this retry loop.
  • #4506 and #4639 are also compaction loops, but distinct: in those, compaction succeeds and reclaims nothing, or is driven by storage exhaustion. Here compaction hard-fails and is retried unconditionally.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Esegui la scansione Python fornita su session-state//events.jsonl ed esamina gli eventi compaction_complete che mostrano errori ripetuti. Traccia il percorso della CLI che ritenta la compaction fallita, quindi verifica che gli errori identici ripetuti siano limitati o soggetti a backoff e che l’utente riceva un avviso visibile invece di tentativi silenziosi che consumano crediti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
shell
Ambito
cli
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Attiva
Chiarezza
Abbastanza chiara
Idoneità per principianti
52/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.