HarperFast / HarperFast/harper

DeployLifecycle exceeds Node's default max listeners on a normal boot, logging a spurious memory-leak warning

Open Beginner friendly
#2,214 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

## Summary

`DeployLifecycle` extends `EventEmitter` without raising the listener cap, but one `deploy:start` listener is registered per live component scope. A normal instance therefore crosses Node's default limit of 10 during startup and logs:

```
(node:1) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 deploy:start
listeners added to [DeployLifecycle]. MaxListeners is 10. Use emitter.setMaxListeners() to increase limit
```

This appears to be a false positive rather than a leak: the listeners are added and removed in matched pairs, so the count reflects how many component scopes are concurrently loaded, not unbounded growth.

## Where

On `origin/main`:

- `components/deployLifecycle.ts:51` — `class DeployLifecycle extends EventEmitter<...>`, no `setMaxListeners()`
- `components/Scope.ts` — registers `deployLifecycle.on('deploy:start', ...)` per scope and removes it with the matching `.off(...)` on teardown
- `components/componentLoader.ts` — same add/remove pairing for its own handler

## Why it is worth fixing anyway

The warning says "Possible EventEmitter memory leak detected" on a healthy boot, so it trains operators to ignore a message that would be meaningful if the count ever *did* start climbing across repeated `deploy_component` calls. It also fires on any instance with more than ~10 components, which is not an unusual shape.

## Suggested fix

Call `setMaxListeners()` on the `DeployLifecycle` instance with a bound that reflects "one per component scope" (or `0`/`Infinity` if the pairing is considered authoritative). If the intent is instead that only a small fixed number of listeners should ever exist, then the per-scope registration is the thing to revisit — but the `.on`/`.off` pairing suggests per-scope is deliberate.

Low priority: log noise, no observed functional impact.

Contributor guide

Open the contributing guide

Research direction

Start in components/deployLifecycle.ts:51, then trace the matching listener registration and teardown in components/Scope.ts and components/componentLoader.ts. Reproduce a normal boot to confirm the warning, establish an appropriate listener bound from the per-scope behavior, and verify that repeated deploy_component calls do not produce spurious warnings or unbounded listener growth.

Written by the indexing model from the issue text.

Assessment

Tech stack
nodejs, typescript
Domain
backend, performance
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.