hermes - 💡(How to fix) Fix bug(tui_gateway): TOCTOU race in _get_db() — concurrent requests can create duplicate SessionDB connections

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

tui_gateway/server.py:_get_db() (line 338) uses a bare if _db is None: guard with no lock. The tui_gateway server handles concurrent HTTP requests, so two simultaneous requests can both see _db is None, both call SessionDB(), and create duplicate database connections.

_db = None  # no lock

def _get_db():
    global _db, _db_error
    if _db is None:          # ← race: two threads enter simultaneously
        from hermes_state import SessionDB
        try:
            _db = SessionDB()  # ← both construct a SessionDB

Root Cause

tui_gateway/server.py:_get_db() (line 338) uses a bare if _db is None: guard with no lock. The tui_gateway server handles concurrent HTTP requests, so two simultaneous requests can both see _db is None, both call SessionDB(), and create duplicate database connections.

_db = None  # no lock

def _get_db():
    global _db, _db_error
    if _db is None:          # ← race: two threads enter simultaneously
        from hermes_state import SessionDB
        try:
            _db = SessionDB()  # ← both construct a SessionDB

Fix Action

Fix

Add _db_lock = threading.Lock() alongside _db = None and apply double-checked locking to _get_db(). Same pattern as #24731 / #24734.

Code Example

_db = None  # no lock

def _get_db():
    global _db, _db_error
    if _db is None:          # ← race: two threads enter simultaneously
        from hermes_state import SessionDB
        try:
            _db = SessionDB()  # ← both construct a SessionDB
RAW_BUFFERClick to expand / collapse

Summary

tui_gateway/server.py:_get_db() (line 338) uses a bare if _db is None: guard with no lock. The tui_gateway server handles concurrent HTTP requests, so two simultaneous requests can both see _db is None, both call SessionDB(), and create duplicate database connections.

_db = None  # no lock

def _get_db():
    global _db, _db_error
    if _db is None:          # ← race: two threads enter simultaneously
        from hermes_state import SessionDB
        try:
            _db = SessionDB()  # ← both construct a SessionDB

Impact

  • SessionDB likely opens a SQLite file connection; duplicate connections can trigger database is locked errors under WAL mode or corrupt write state.
  • The file already imports threading and uses locks elsewhere (_stdout_lock, _cfg_lock) — _get_db was simply missed.

Fix

Add _db_lock = threading.Lock() alongside _db = None and apply double-checked locking to _get_db(). Same pattern as #24731 / #24734.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix bug(tui_gateway): TOCTOU race in _get_db() — concurrent requests can create duplicate SessionDB connections