Skip to content

fix(display): guard isatty() against closed streams via _is_tty property#3056

Merged
teknium1 merged 1 commit intomainfrom
hermes/hermes-7d7ac769
Mar 25, 2026
Merged

fix(display): guard isatty() against closed streams via _is_tty property#3056
teknium1 merged 1 commit intomainfrom
hermes/hermes-7d7ac769

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

Summary

In gateway/Telegram mode, the stdout fd can be closed by executor thread cleanup. KawaiiSpinner.stop() called isatty() on the closed fd, raising ValueError and masking the original error with "I/O operation on closed file".

Instead of a point fix at one call site, adds a _is_tty property that centralizes the closed-stream guard. Both _animate() and stop() now use it. Follows the same (ValueError, OSError) pattern already established in _write().

Inspired by PR #2632 by @bot-deo88 (improved from point fix to centralized property).

Live PTY verified

  • Banner, spinner, tool progress, response boxes, status bar all clean
  • Two consecutive tool calls with no artifacts
  • Zero garbled ANSI sequences
In gateway/Telegram mode, the stdout fd can be closed by executor
thread cleanup. KawaiiSpinner.stop() called isatty() on the closed fd,
raising ValueError and masking the original error.

Instead of a point fix, add a _is_tty property that centralizes the
closed-stream guard — both _animate() and stop() now use it. Follows
the same (ValueError, OSError) pattern already in _write().

Inspired by PR #2632 by bot-deo88.
@teknium1 teknium1 merged commit 14cf2d8 into main Mar 25, 2026
InB4DevOps pushed a commit to InB4DevOps/hermes-agent that referenced this pull request Mar 25, 2026
…rty (NousResearch#3056)

In gateway/Telegram mode, the stdout fd can be closed by executor
thread cleanup. KawaiiSpinner.stop() called isatty() on the closed fd,
raising ValueError and masking the original error.

Instead of a point fix, add a _is_tty property that centralizes the
closed-stream guard — both _animate() and stop() now use it. Follows
the same (ValueError, OSError) pattern already in _write().

Inspired by PR NousResearch#2632 by bot-deo88.
outsourc-e pushed a commit to outsourc-e/hermes-agent that referenced this pull request Mar 26, 2026
…rty (NousResearch#3056)

In gateway/Telegram mode, the stdout fd can be closed by executor
thread cleanup. KawaiiSpinner.stop() called isatty() on the closed fd,
raising ValueError and masking the original error.

Instead of a point fix, add a _is_tty property that centralizes the
closed-stream guard — both _animate() and stop() now use it. Follows
the same (ValueError, OSError) pattern already in _write().

Inspired by PR NousResearch#2632 by bot-deo88.
StreamOfRon pushed a commit to StreamOfRon/hermes-agent that referenced this pull request Mar 29, 2026
…rty (NousResearch#3056)

In gateway/Telegram mode, the stdout fd can be closed by executor
thread cleanup. KawaiiSpinner.stop() called isatty() on the closed fd,
raising ValueError and masking the original error.

Instead of a point fix, add a _is_tty property that centralizes the
closed-stream guard — both _animate() and stop() now use it. Follows
the same (ValueError, OSError) pattern already in _write().

Inspired by PR NousResearch#2632 by bot-deo88.
apexscaleai added a commit to apexscaleai/hermes-agent that referenced this pull request Mar 31, 2026
Two fixes from production incident on March 30, 2026:

1. gateway/run.py:5697 - Change logger.debug to logger.error for cron tick
   errors. Debug level was silently swallowing exceptions that caused specific
   jobs to fail/miss.

2. cron/scheduler.py - Store PID in lock file for stale lock detection.
   Previously the lock file was 0-bytes, making it impossible to detect
   stale locks from crashed processes. Now writes PID and checks if the
   process is still running before treating a lock as valid.

The display.py isatty() fix (issue NousResearch#3056) was already applied in commit
14cf2d8.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
apexscaleai added a commit to apexscaleai/hermes-agent that referenced this pull request Mar 31, 2026
Two fixes from production incident on March 30, 2026:

1. gateway/run.py:5697 - Change logger.debug to logger.error for cron tick
   errors. Debug level was silently swallowing exceptions that caused specific
   jobs to fail/miss.

2. cron/scheduler.py - Store PID in lock file for stale lock detection.
   Previously the lock file was 0-bytes, making it impossible to detect
   stale locks from crashed processes. Now writes PID and checks if the
   process is still running before treating a lock as valid.

The display.py isatty() fix (issue NousResearch#3056) was already applied in commit
14cf2d8.
apexscaleai added a commit to apexscaleai/hermes-agent that referenced this pull request Mar 31, 2026
Two fixes from production incident on March 30, 2026:

1. gateway/run.py:5697 - Change logger.debug to logger.error for cron tick
   errors. Debug level was silently swallowing exceptions that caused specific
   jobs to fail/miss.

2. cron/scheduler.py - Store PID in lock file for stale lock detection.
   Previously the lock file was 0-bytes, making it impossible to detect
   stale locks from crashed processes. Now writes PID and checks if the
   process is still running before treating a lock as valid.

The display.py isatty() fix (issue NousResearch#3056) was already applied in commit
14cf2d8.

(cherry picked from commit 06d7bad)
apexscaleai added a commit to apexscaleai/hermes-agent that referenced this pull request Mar 31, 2026
Two fixes from production incident on March 30, 2026:

1. gateway/run.py:5697 - Change logger.debug to logger.error for cron tick
   errors. Debug level was silently swallowing exceptions that caused specific
   jobs to fail/miss.

2. cron/scheduler.py - Store PID in lock file for stale lock detection.
   Previously the lock file was 0-bytes, making it impossible to detect
   stale locks from crashed processes. Now writes PID and checks if the
   process is still running before treating a lock as valid.

The display.py isatty() fix (issue NousResearch#3056) was already applied in commit
14cf2d8.

(cherry picked from commit 06d7bad)

Co-authored-by: apexscaleai <226130037+apexscaleai@users.noreply.github.com>
(cherry picked from commit 4ec1adf2cec241ce9cb1bfe6f56772d6dc9b40f1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant