Description
The /update command triggered from Telegram (or any non-TTY context) fails with exit code 1 when the update introduces new config options that trigger the migration prompt.
Root cause
In hermes_cli/main.py, the cmd_update() function calls input("Would you like to configure them now? [Y/n]: ") unconditionally (around line 2819). When /update is triggered from Telegram, the update process is spawned via nohup bash -c ... (or systemd-run --scope) with no TTY attached. input() receives EOF immediately, which causes the function to either crash or exit with code 1 before reaching the gateway restart logic.
Impact
- The git pull and dependency install succeed, so the code is updated on disk
- But the gateway never restarts, so the old code keeps running in memory
- The user gets a failure notification ("update failed") even though the code was partially updated
- The next
/update from Telegram reports "already up to date" since the pull already landed
Reproduction
- Set up Hermes with Telegram as the control channel and launchd as the service manager
- Wait for a release that introduces new config options (triggering
needs_migration)
- Send
/update via Telegram
- Observe exit code 1 and gateway not restarted
Suggested fix
Guard the input() call with a TTY check:
if sys.stdin.isatty():
response = input("Would you like to configure them now? [Y/n]: ").strip().lower()
else:
print("Non-interactive session — skipping config migration.")
print("Run 'hermes config migrate' later to configure.")
response = "n"
This allows the update to complete and restart the gateway in non-interactive contexts, while preserving the interactive prompt for terminal users.
Environment
- Hermes v0.4.0 (v2026.3.23+)
- macOS (Darwin), Mac mini M1
- Gateway managed by launchd
- Telegram as primary control channel
Description
The
/updatecommand triggered from Telegram (or any non-TTY context) fails with exit code 1 when the update introduces new config options that trigger the migration prompt.Root cause
In
hermes_cli/main.py, thecmd_update()function callsinput("Would you like to configure them now? [Y/n]: ")unconditionally (around line 2819). When/updateis triggered from Telegram, the update process is spawned vianohup bash -c ...(orsystemd-run --scope) with no TTY attached.input()receives EOF immediately, which causes the function to either crash or exit with code 1 before reaching the gateway restart logic.Impact
/updatefrom Telegram reports "already up to date" since the pull already landedReproduction
needs_migration)/updatevia TelegramSuggested fix
Guard the
input()call with a TTY check:This allows the update to complete and restart the gateway in non-interactive contexts, while preserving the interactive prompt for terminal users.
Environment