Problem
When running a command through Context.run(..., pty=True) on macOS, keyboard input can terminate Invoke's handle_stdin worker with:
DEBUG Encountered exception SystemError('buffer overflow') in thread for 'handle_stdin'
The issue is reproducible with invoke-toolkit==0.0.68, invoke==3.0.3, and Python 3.14 on macOS. Arrow/function keys are sufficient to trigger it.
Root Cause
invoke.terminals.bytes_to_read() calls fcntl.ioctl(input_, termios.FIONREAD, b" ") when the input reports isatty() == True. On macOS, the ioctl result can exceed the two-byte buffer expected by struct.unpack("h", ...), causing Python to raise SystemError("buffer overflow").
The exception is raised inside Invoke's handle_stdin thread and then logged by the thread exception handler.
Fix
Make the terminal-byte availability probe safe on macOS/POSIX. Possible approaches:
- use a sufficiently sized mutable buffer and unpack the documented result width;
- avoid
FIONREAD and read one byte after select() reports readiness; or
- catch/handle the platform-specific ioctl failure and fall back to a one-byte read.
Please add a regression test that exercises bytes_to_read() or handle_stdin with a PTY and keyboard input, including escape-sequence keys.
Temporary downstream workaround: wrap the input stream so isatty() returns False, put the terminal in cbreak mode, and pass it as in_stream; this avoids the FIONREAD branch but should not be necessary for users.
Problem
When running a command through
Context.run(..., pty=True)on macOS, keyboard input can terminate Invoke'shandle_stdinworker with:The issue is reproducible with
invoke-toolkit==0.0.68,invoke==3.0.3, and Python 3.14 on macOS. Arrow/function keys are sufficient to trigger it.Root Cause
invoke.terminals.bytes_to_read()callsfcntl.ioctl(input_, termios.FIONREAD, b" ")when the input reportsisatty() == True. On macOS, the ioctl result can exceed the two-byte buffer expected bystruct.unpack("h", ...), causing Python to raiseSystemError("buffer overflow").The exception is raised inside Invoke's
handle_stdinthread and then logged by the thread exception handler.Fix
Make the terminal-byte availability probe safe on macOS/POSIX. Possible approaches:
FIONREADand read one byte afterselect()reports readiness; orPlease add a regression test that exercises
bytes_to_read()orhandle_stdinwith a PTY and keyboard input, including escape-sequence keys.Temporary downstream workaround: wrap the input stream so
isatty()returnsFalse, put the terminal in cbreak mode, and pass it asin_stream; this avoids theFIONREADbranch but should not be necessary for users.