Failed compaction is retried unchanged on every turn: unbounded billed retries, monotonic context growth, no user-visible error
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Shell
- Estrellas
- 11.2k
- Forks
- 1.9k
- Merge medio
- 14 h 16 min
- PR fusionados (30 d)
- 6
Descripción
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:
- Run a session with an MCP server whose tools are deferred.
- Surface and call a deferred MCP tool.
- Let the session grow until
trigger: thresholdcompaction fires. - Observe
session.compaction_completewithsuccess: 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:
- Back off. Exponential backoff with a cap, and stop retrying after N consecutive identical failures.
- Surface it. A visible warning that compaction is failing and why. Today the only signal is credit burn.
- Reconcile or fall back. If the payload is structurally rejected, either repair it (for the case above: build
toolsfrom 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.
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Ejecuta el análisis de Python proporcionado contra session-state//events.jsonl e inspecciona los eventos compaction_complete que muestran fallos repetidos. Rastrea la ruta de la CLI que reintenta la compaction fallida y verifica después que los fallos idénticos repetidos estén limitados o sujetos a backoff, y que el usuario reciba una advertencia visible en lugar de reintentos silenciosos que consuman créditos.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- shell
- Área
- cli
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Activo
- Claridad
- Bastante claro
- Aptitud para principiantes
- 52/100