Summary
On Windows, hermes chat -q "<prompt>" crashes with prompt_toolkit.output.win32.NoConsoleScreenBufferError: No Windows console found. Are you running cmd.exe? whenever Hermes' stdout is not a real console — e.g. when it is spawned by another process with stdio: pipe (any automation/orchestration tool, CI, or programmatic integration). This makes the documented "single query (non-interactive mode)" flag unusable from any Windows automation context, since capturing the response text inherently requires piping stdout.
Environment
- Hermes Agent v0.10.0 (2026.4.16, upstream
4a69a662)
- Windows (child process spawned via Node.js
child_process.spawn with stdio: ['ignore','pipe','pipe'], shell: false)
prompt_toolkit output backend selection
Steps to reproduce
Spawn Hermes as a non-console child process (this is exactly what any orchestrator/automation wrapper does to capture output):
const { spawn } = require('child_process');
const child = spawn('hermes', ['chat', '-q', 'Reply with exactly the single word: PONG', '-Q'], {
stdio: ['ignore', 'pipe', 'pipe'],
shell: false,
});
or equivalently from a shell with stdout redirected to a pipe/file rather than a terminal:
hermes chat -q "Reply with exactly the single word: PONG" -Q | Out-File out.txt
Actual result
Exit code 1, no query response, and (without -Q, or in some -Q cases too) a traceback ending in:
Traceback (most recent call last):
...
File "...\hermes-agent\cli.py", line 8321, in chat
_cprint(f"{_DIM}Initializing agent...{_RST}")
File "...\hermes-agent\cli.py", line 1254, in _cprint
_pt_print(_PT_ANSI(text))
File "...\prompt_toolkit\shortcuts\utils.py", line 111, in print_formatted_text
output = get_app_session().output
File "...\prompt_toolkit\application\current.py", line 67, in output
self._output = create_output()
File "...\prompt_toolkit\output\defaults.py", line 91, in create_output
return Win32Output(stdout, default_color_depth=color_depth_from_env)
File "...\prompt_toolkit\output\win32.py", line 115, in __init__
info = self.get_win32_screen_buffer_info()
File "...\prompt_toolkit\output\win32.py", line 219, in get_win32_screen_buffer_info
raise NoConsoleScreenBufferError
prompt_toolkit.output.win32.NoConsoleScreenBufferError: No Windows console found. Are you running cmd.exe?
Separately, without forcing PYTHONIOENCODING=utf-8 in the child environment, the banner/spinner rendering (box-drawing + braille characters) also raises UnicodeEncodeError: 'charmap' codec can't encode characters ... when stdout falls back to the default Windows console codepage (cp1252) instead of UTF-8 — a second, related issue with the same root cause (assuming a real interactive console is always present).
Root cause
prompt_toolkit/output/defaults.py::create_output() has this branch on sys.platform == "win32":
if sys.platform == "win32":
if is_win_vt100_enabled():
return Windows10_Output(...)
if is_conemu_ansi():
return ConEmuOutput(...)
else:
return Win32Output(stdout, default_color_depth=color_depth_from_env)
Unlike the POSIX branch just below it (which checks stdout.isatty() and falls back to PlainTextOutput when stdout is not a terminal), the Windows branch has no such fallback — it unconditionally tries Win32Output, which calls GetConsoleScreenBufferInfo on the process's STD_OUTPUT_HANDLE. When that handle is a pipe (not a console), the Win32 API call fails and Win32Output.__init__ raises NoConsoleScreenBufferError with no graceful degradation path.
This means any non-interactive/automated invocation of Hermes on Windows is currently broken, since capturing output for programmatic use always requires stdio: pipe.
Suggested fix
Either (or both):
- In Hermes' own
cli.py _cprint, catch prompt_toolkit.output.win32.NoConsoleScreenBufferError (and ideally check sys.stdout.isatty() up front) and fall back to plain print() when no real console is attached — mirrors what prompt_toolkit already does correctly on POSIX.
- Upstream in
prompt_toolkit itself: add an isatty()/pipe check to the win32 branch of create_output() (parity with the POSIX branch), returning PlainTextOutput when stdout isn't a real console, instead of unconditionally requiring Win32Output's console-buffer query to succeed.
Workaround
Set PYTHONIOENCODING=utf-8 in the child environment to avoid the separate charmap crash on the banner text, and use -Q (quiet mode) to suppress most _cprint calls — but this does not fully avoid the NoConsoleScreenBufferError path for every non-interactive invocation on Windows, since some _cprint calls still fire under -q/-Q (e.g. the "Initializing agent..." message) whenever there's no attached console at all.
Happy to test a fix against a real automation harness if useful — this was found while wiring Hermes up as a pluggable local LLM backend in an orchestration tool and confirmed via a minimal repro spawning hermes.exe directly with stdio: pipe, isolating it from any surrounding tooling.
Summary
On Windows,
hermes chat -q "<prompt>"crashes withprompt_toolkit.output.win32.NoConsoleScreenBufferError: No Windows console found. Are you running cmd.exe?whenever Hermes' stdout is not a real console — e.g. when it is spawned by another process withstdio: pipe(any automation/orchestration tool, CI, or programmatic integration). This makes the documented "single query (non-interactive mode)" flag unusable from any Windows automation context, since capturing the response text inherently requires piping stdout.Environment
4a69a662)child_process.spawnwithstdio: ['ignore','pipe','pipe'],shell: false)prompt_toolkitoutput backend selectionSteps to reproduce
Spawn Hermes as a non-console child process (this is exactly what any orchestrator/automation wrapper does to capture output):
or equivalently from a shell with stdout redirected to a pipe/file rather than a terminal:
Actual result
Exit code 1, no query response, and (without
-Q, or in some-Qcases too) a traceback ending in:Separately, without forcing
PYTHONIOENCODING=utf-8in the child environment, the banner/spinner rendering (box-drawing + braille characters) also raisesUnicodeEncodeError: 'charmap' codec can't encode characters ...when stdout falls back to the default Windows console codepage (cp1252) instead of UTF-8 — a second, related issue with the same root cause (assuming a real interactive console is always present).Root cause
prompt_toolkit/output/defaults.py::create_output()has this branch onsys.platform == "win32":Unlike the POSIX branch just below it (which checks
stdout.isatty()and falls back toPlainTextOutputwhen stdout is not a terminal), the Windows branch has no such fallback — it unconditionally triesWin32Output, which callsGetConsoleScreenBufferInfoon the process'sSTD_OUTPUT_HANDLE. When that handle is a pipe (not a console), the Win32 API call fails andWin32Output.__init__raisesNoConsoleScreenBufferErrorwith no graceful degradation path.This means any non-interactive/automated invocation of Hermes on Windows is currently broken, since capturing output for programmatic use always requires
stdio: pipe.Suggested fix
Either (or both):
cli.py_cprint, catchprompt_toolkit.output.win32.NoConsoleScreenBufferError(and ideally checksys.stdout.isatty()up front) and fall back to plainprint()when no real console is attached — mirrors whatprompt_toolkitalready does correctly on POSIX.prompt_toolkititself: add anisatty()/pipe check to thewin32branch ofcreate_output()(parity with the POSIX branch), returningPlainTextOutputwhen stdout isn't a real console, instead of unconditionally requiringWin32Output's console-buffer query to succeed.Workaround
Set
PYTHONIOENCODING=utf-8in the child environment to avoid the separate charmap crash on the banner text, and use-Q(quiet mode) to suppress most_cprintcalls — but this does not fully avoid theNoConsoleScreenBufferErrorpath for every non-interactive invocation on Windows, since some_cprintcalls still fire under-q/-Q(e.g. the "Initializing agent..." message) whenever there's no attached console at all.Happy to test a fix against a real automation harness if useful — this was found while wiring Hermes up as a pluggable local LLM backend in an orchestration tool and confirmed via a minimal repro spawning
hermes.exedirectly withstdio: pipe, isolating it from any surrounding tooling.