Current state — July 30, 2026: PR #74304 remains open. The automated Hermes Sweeper recommends keep_open with high salvageability and agrees that the fix and regression test match the reader-shutdown bug. There is still no human maintainer review or upstream CI attached to the PR.

Contributor note: I am a fledgling developer, and I tried to make this change carefully. I reproduced the bug, narrowed the claim, wrote a direct regression test, ran the focused tests and Ruff, and had the final diff independently reviewed with Opus 5 before asking upstream to look at it. That does not replace maintainer review or CI; it is the process I used to reduce the odds of wasting their time.

A long-lived Hermes process ran out of file descriptors while holding repeated SQLite database and WAL handles. The confirmed bug was smaller than the whole incident: SessionDB could track reader connections created by worker threads, but its owner thread could not close them during shutdown.

The missing detail was one SQLite connection option: check_same_thread=False.

SessionDB reader shutdown before and after PR #74304 Before the fix, a worker-created thread-bound connection rejects owner-thread close and remains open. After the fix, the owner drains and closes the connection after the worker exits. SessionDB reader shutdown same reader lifecycle · one connection flag changes the outcome BEFORE default check_same_thread=True PR #74304 check_same_thread=False worker thread creates reader SQLite reader bound to worker tracked in _read_conns worker thread creates + exits SQLite reader thread-local in use cross-thread close allowed owner thread SessionDB.close() ProgrammingError owner thread SessionDB.close() drain succeeds exception swallowed → reader survives database / WAL descriptors remain open reader closes → registry drains regression proof: “closed database” Scope boundary: shutdown after the worker finishes — not arbitrary close during an in-flight query.

The reader stays thread-local during normal use. Only the shutdown drain crosses threads.

What the PR changes

2files changed
30added lines
10 / 10focused tests passing
APPROVEOpus 5 final review
KEEP OPENHermes Sweeper · high salvageability

Why the test got smaller

The first version counted process file descriptors and coordinated several worker threads. That tested the symptom indirectly and added platform noise. The final test is simpler and stronger: it keeps one worker-created connection, lets the worker finish, calls SessionDB.close() from the owner, and proves the connection is actually closed.

QuestionAnswer
Does the test catch the old behavior?Yes. Current upstream produces the original same-thread error instead of closed database.
Does this prove every FD leak is gone?No. It fixes one confirmed SessionDB reader lifecycle class.
What did upstream automation say?Hermes Sweeper recommended keep_open, rated salvageability high, and said the one-line connection-policy change and lifecycle test align with the bug.
Has upstream CI approved it?Not yet. GitHub currently reports no checks for the fork head.

The important boundary: disabling SQLite's Python thread-affinity check is not a promise that arbitrary concurrent operations are safe. This patch covers cleanup after the reader's worker has finished.

Read Hermes PR #74304 →

Small bug, small patch, direct test. The hard part was making the claim no larger than the evidence.