Skip to content

fix(windows): stop spamming cwd-missing + tirith-spawn warnings on every terminal call#26618

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-7e042e2d
May 15, 2026
Merged

fix(windows): stop spamming cwd-missing + tirith-spawn warnings on every terminal call#26618
teknium1 merged 1 commit into
mainfrom
hermes/hermes-7e042e2d

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Two Windows / Git Bash log-spam fixes surfaced by a user-captured Hermes log: 19× identical LocalEnvironment cwd '/c/Users/x' is missing on disk warnings and 15× identical tirith spawn failed: [WinError 2] warnings in a single short session. Behavior is unchanged in both cases — only log volume drops.

Changes

tools/environments/local.py — Git Bash's pwd -P emits /c/Users/x. The base-class _extract_cwd_from_output was assigning this verbatim to self.cwd, then _resolve_safe_cwd's os.path.isdir('/c/...') returned False on Windows, triggering the warning on every terminal call. The pre-existing Windows-path translation inside _run_bash ran after the safe-cwd check, so it could never prevent the warning.

tools/tirith_security.py — When tirith isn't installed yet (background install in flight, or marked failed for the day) and the configured path stays as the bare string "tirith", every subprocess.run([tirith_path, ...]) raises OSError and logs tirith spawn failed: [WinError 2]... on every command. fail_open=True means behavior is correct, but the log noise is severe.

  • _warn_once(key, ...) thread-safe dedupe helper.
  • Three hot-path warnings (tirith path resolved to None, tirith spawn failed: ..., tirith timed out after Ns) now log once per (exception class, errno) / timeout-value / path-none key.
  • Dedupe set is cleared on _clear_install_failed so a successful install lets a subsequent failure surface again.

Validation

Before After
LocalEnvironment cwd '/c/Users/x' is missing on disk warnings per session on Windows one per terminal call zero (or one, if the directory genuinely is deleted)
tirith spawn failed: [WinError 2] warnings per session when binary not installed one per terminal call one per (exception class, errno) for the process lifetime
test_local_env_windows_msys.py n/a 12/12 new tests passing
test_local_env_cwd_recovery.py 7/7 7/7 (no regressions, #17558 still covered)
test_tirith_security.py 63/63 67/67 (4 new dedupe tests, 63 pre-existing)
test_base_environment.py + neighbours passing 37/37, no regressions
tests/tools/ `tirith local_env terminal_security` slice

Test plan

scripts/run_tests.sh tests/tools/test_local_env_windows_msys.py \
                     tests/tools/test_local_env_cwd_recovery.py \
                     tests/tools/test_tirith_security.py

Linux CI fakes the Windows code path by patching tools.environments.local._IS_WINDOWS = True plus _msys_to_windows_path to return a real tmp_path; the cwd validation path is identical.

Out of scope (also found in the same log capture but not fixed here)

  • Desktop SIGTERM→respawn loop (25 cycles in desktop.log) — the desktop wrapper is a separate Electron app, not in this repo.
  • whatsapp connect timed out → gateway aborts — already fixed on main; gateway now stays alive in degraded mode for cron jobs (the captured log was on an older build).
  • hermes update: [WinError 32] hermes.exe in use — the warning is misleading but the existing .exe.old.<ts> quarantine + ZIP-fallback path completes successfully.
  • llama-3-70b / gemma4:latest 404 / connection errors — user-side Ollama config, not Hermes.
  • No allowlists / no platforms enabled — actionable user warnings, working as designed.

…ery terminal call

Two log-spam fixes surfaced by a Windows user (Git Bash + Python 3.11.9):

1. LocalEnvironment cwd warn spam
   ============================
   Git Bash's `pwd -P` emits paths like `/c/Users/x`. The base-class
   `_extract_cwd_from_output` was assigning this verbatim to `self.cwd`
   without validation, then `_resolve_safe_cwd`'s `os.path.isdir(/c/...)`
   returned False on Windows, triggering:

       LocalEnvironment cwd '/c/Users/NVIDIA' is missing on disk;
       falling back to '/' so terminal commands keep working.

   ...on every terminal call. The pre-existing Windows-path translation
   inside `_run_bash` ran AFTER the safe-cwd check, so it could never
   prevent the warning.

   Fix:
   - New `_msys_to_windows_path` helper (idempotent, no-op off Windows).
   - `_resolve_safe_cwd` normalizes before `isdir`, so a valid MSYS path
     is recognized as the real directory it points at.
   - `LocalEnvironment._update_cwd` and a new override of
     `_extract_cwd_from_output` translate + validate before mutating
     `self.cwd`. Stale / non-existent marker paths roll back to the
     previous cwd instead of clobbering it.
   - The fallback warning still fires when the directory really is gone
     (deletion-recovery scenario from #17558 still covered).

2. tirith spawn-failed warn spam
   =============================
   When tirith isn't installed (background install in flight, or marked
   failed for the day) and the configured path stays as the bare string
   `tirith`, every `subprocess.run([tirith_path, ...])` raises OSError
   and logged:

       tirith spawn failed: [WinError 2] The system cannot find the file specified

   ...on every command. fail_open=True means behaviour is correct, but
   the log noise is severe.

   Fix:
   - `_warn_once(key, ...)` thread-safe dedupe helper.
   - Three hot-path warnings (`tirith path resolved to None`,
     `tirith spawn failed: ...`, `tirith timed out after Ns`) now log
     once per (exception class, errno) / timeout-value / path-none key.
   - Dedupe set is cleared on `_clear_install_failed` so a successful
     install lets a subsequent failure surface again.

Tests
=====
- `tests/tools/test_local_env_windows_msys.py`: 12 tests covering the
  MSYS→Windows translator, the resolve fast-path, update_cwd validation,
  and extract_cwd_from_output rollback.
- `tests/tools/test_tirith_security.py`: 4 new dedupe tests (15 spawn
  failures → 1 log line; distinct exc types → 2 lines; timeout dedupe;
  path-None dedupe).

Targeted runs:
  test_local_env_windows_msys.py      12 passed
  test_local_env_cwd_recovery.py       7 passed (pre-existing, no regressions)
  test_tirith_security.py             67 passed (63 pre-existing + 4 new)
  test_base_environment + local_*    37 passed (no regressions)
  test_local_env_blocklist + neighbours  114 passed

Reported via Hermes log capture: 19× cwd warnings + 15× tirith warnings
in a single short session.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-7e042e2d vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8300 on HEAD, 8299 on base (🆕 +1)

🆕 New issues (1):

Rule Count
unresolved-import 1
First entries
tests/tools/test_local_env_windows_msys.py:24: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`

✅ Fixed issues: none

Unchanged: 4334 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists backend/local Local shell execution tool/terminal Terminal execution and process management labels May 15, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: Fixes #23845 (tirith spawn spam) and #23846 (MSYS cwd warning). Supersedes competing fix PRs #23855 and #23880 (both address only the tirith half).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend/local Local shell execution P2 Medium — degraded but workaround exists tool/terminal Terminal execution and process management type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants