Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

[Bug] Cancelling retry backoff leaves a referenced timeout alive until the original delay expires

Abierto Apto para principiantes
#4,334 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
76/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
node.js, typescript
Área
backend

Línea de trabajo

Empieza leyendo packages/agent-core-v2/src/_base/utils/retry.ts, especialmente sleepForRetry y cómo utiliza sleep y abortable; el informe incluye una reproducción en Node.js que muestra el timeout restante después de la cancelación. Revisa las pruebas existentes de este helper y añade cobertura para la cancelación y la finalización normal. Se considera terminado cuando la cancelación se rechaza con el mismo motivo y se borra el timeout, mientras que una espera no cancelada sigue completándose después de su demora.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

What version of Kimi Code is running?

Source-level reproduction at current main 44cdf8f4039e2ff20d3fe8a4e7868bd90fd786e1. The affected retry.ts and abort.ts are byte-identical in the latest release tag @moonshot-ai/[email protected] (commit b5e28fd6beac752a2cdcc0ff2f5fdf40e6494fbb). I tested the real source helper, not an installed CLI build.

Which open platform/subscription and model were you using?

Not applicable: offline CPU reproduction, no provider requests or API key.

What platform is your computer?

macOS arm64, Darwin 25.5.0 arm64 arm, Node.js v24.19.0.

What issue are you seeing?

Cancelling sleepForRetry immediately rejects its Promise with the original cancellation reason, but leaves its referenced timeout alive until the original backoff expires. An otherwise idle Node process therefore cannot exit naturally after the caller has already caught the cancellation.

This is not a claim that cancellation fails to reject, that another provider request is sent, or that the complete CLI/TUI is permanently frozen.

What steps can reproduce the bug?

From the repository root at the commit above, run with Node 24.15 or newer. No dependency installation is needed for these two modules:

node --input-type=module <<'JS'
import { sleepForRetry } from './packages/agent-core-v2/src/_base/utils/retry.ts';

const started = performance.now();
const controller = new AbortController();
const reason = new Error('cancel this retry');
const pending = sleepForRetry(650, controller.signal);
controller.abort(reason);
try {
  await pending;
} catch (error) {
  console.log('original reason:', error === reason);
}
console.log('active resources:', process.getActiveResourcesInfo());
console.log('cancelled after ms:', Math.round(performance.now() - started));
process.once('beforeExit', () => {
  console.log('beforeExit after ms:', Math.round(performance.now() - started));
});
JS

Actual output on my machine (non-timer handles can vary):

original reason: true
active resources: [ 'FSReqCallback', 'PipeWrap', 'PipeWrap', 'Timeout' ]
cancelled after ms: 1
beforeExit after ms: 651
What is the expected behavior?

After cancellation, reject promptly with the same reason and clear the pending timeout. With no remaining work, the process should be able to exit without waiting for the cancelled delay. Normal, non-cancelled waits should still complete after their delay.

Additional information
  • The helper creates sleep(delayMs) before racing it with abortable; sleep discards the timer handle. Rejecting the outer Promise does not cancel that timer.
  • Actual callers include full-compaction retries and the opt-in infinite LLM retry path. The issue is the leftover resource, not whether those callers stop retrying.
  • In three fresh control runs, cancellation immediately and one event-loop turn after starting 500ms, 32s and 60s sleeps consistently left one active timeout per cancelled wait. Pre-aborted signals created none; normal completion cleared the timer. Long-delay fixtures explicitly cleaned up the observed handles after measurement.
  • Independent child processes rejected immediately but stayed alive for about 650ms in all runs. Pre-aborted controls and a test-only control that clears the captured timer on abort exited immediately. Native node:timers/promises cancellation also left no pending timer.
  • No repository implementation was changed. No live inference, complete CLI/TUI lifecycle, Windows/Linux, or full-repository test suite was exercised.
  • Related reports #1796, #1860 and #2025 concern rate-limit handling/visibility before cancellation. This reproduces after cancellation has already been caught, without HTTP or provider errors.
  • #2855 addresses delayed cancellation inside provider SDK retries; rejection here is already immediate. The CLI also has a force-exit fallback from #1233, so I am not claiming that every kimi -p run hangs. This report is specifically about the engine helper retaining a referenced timer after cancellation.
Contribution
  • I am willing to submit a PR for this bug fix myself (please wait for maintainer approval in this issue first)
Lenguaje dominante
TypeScript
Estrellas
7.9k
Forks
1.3k
Merge medio
1 d 12 h
PR fusionados (30 d)
103

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de MoonshotAI/kimi-code

Todos los issues de MoonshotAI/kimi-code

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.