ChainSafe / ChainSafe/lodestar

[CLI] showProgress leaves an abort listener after completion

Open Beginner friendly
#9,856 1 comment 0 reactions 0 assignees View on GitHub
meta-bug
Dominant language
TypeScript
Stars
1.4k
Forks
483
Avg merge
1d 16h
Merged PRs (30d)
150

Description

### Describe the bug

`packages/cli/src/util/progress.ts` registers an anonymous `abort` listener in `showProgress()`:

```ts
signal.addEventListener("abort", () => {
clearInterval(progressIntervalId);
});
```

When progress reaches total, the interval is cleared, but the abort listener is not removed.

If multiple progress tasks share a long-lived AbortController, every completed task leaves a listener closure attached to the signal. In a long-running CLI process, this can retain unnecessary references and may eventually cause listener accumulation warnings.

### Expected behavior

When progress completes normally, the interval and its abort listener should both be cleaned up.

The abort path should also perform the same cleanup.

### Steps to reproduce

1. Create a long-lived AbortController.
2. Repeatedly call showProgress() with the same controller.signal.
3. Complete each progress task by reaching its total.
4. Observe that the interval is cleared but the abort listener remains registered on the signal.

### Additional context

Affected file:
packages/cli/src/util/progress.ts

The listener should be stored in a named function and removed by a shared cleanup function. Using {once: true} alone is insufficient because the signal may never abort after normal completion.

This also applies to total === 0, where no interval is started but the abort listener is still registered.

### Operating system

macOS

### Lodestar version or commit hash

unstable, commit bd3a76e069e3b0660addf88b686e414eafee6036

Contributor guide

Open the contributing guide

Research direction

Start in packages/cli/src/util/progress.ts and read showProgress(), focusing on the normal completion, abort, and total === 0 paths. Verify that each path cleans up both the interval and abort listener, including repeated tasks sharing one AbortController.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
86/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.