{"record":{"id":"faac66ddadcb7faa","repo":"locustio/locust","slug":"terminal-was-not-a-tty-keyboard-input-disabled","errorCode":null,"errorMessage":"Terminal was not a tty. Keyboard input disabled","messagePattern":"Terminal was not a tty\\. Keyboard input disabled","errorType":"exception","errorClass":"InitError","httpStatus":null,"severity":"warning","filePath":"locust/input_events.py","lineNumber":38,"sourceCode":"    )\nelse:\n    import select\n    import termios\n    import tty\n\n\nclass InitError(Exception):\n    pass\n\n\nclass UnixKeyPoller:\n    def __init__(self):\n        if sys.stdin.isatty():\n            self.stdin = sys.stdin.fileno()\n            self.tattr = termios.tcgetattr(self.stdin)\n            tty.setcbreak(self.stdin, termios.TCSANOW)\n        else:\n            raise InitError(\"Terminal was not a tty. Keyboard input disabled\")\n\n    def cleanup(self):\n        termios.tcsetattr(self.stdin, termios.TCSANOW, self.tattr)\n\n    def poll(_self):\n        dr, dw, de = select.select([sys.stdin], [], [], 0)\n        if not dr == []:\n            return sys.stdin.read(1)\n        return None\n\n\nclass WindowsKeyPoller:\n    def __init__(self):\n        if sys.stdin.isatty():\n            try:\n                self.read_handle = GetStdHandle(STD_INPUT_HANDLE)\n                self.read_handle.SetConsoleMode(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT)\n                self.cur_event_length = 0","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/locustio/locust/blob/f391a716e12c2c712e80b5835e877b7933397453/locust/input_events.py#L20-L56","documentation":"The non-Windows keyboard listener needs to put the terminal in cbreak mode, which requires stdin to be a TTY. If `sys.stdin.isatty()` is false it raises InitError, disabling keyboard input (e.g. the web-UI quit hotkey listener).","triggerScenarios":"Running locust with stdin redirected from a file or pipe; running under a process manager/cron/CI without a terminal; detaching stdin via nohup.</br>","commonSituations":"`locust --web ... < /dev/null` or service wrappers without a TTY; Docker containers run without -t; CI pipelines starting the web UI.","solutions":["Run locust in a real terminal (TTY) if keyboard input is needed","If no TTY is available, this InitError is expected/benign — run headless (`--headless`) or ignore the listener error","In Docker use `docker run -it` when interactive key events are desired"],"exampleFix":"// before\nsubprocess.run(\"locust\", shell=True)  # stdin is a pipe\n// after\nimport pty, os\nsubprocess.run(\"locust\", shell=True, stdin=os.open(\"/dev/tty\", os.O_RDONLY))\n# or run headless: locust --headless","handlingStrategy":"try-catch","validationCode":"import sys\nif not sys.stdin.isatty():\n    print(\"No TTY: keyboard input listener unavailable; run --headless\")","typeGuard":"def has_tty() -> bool:\n    import sys\n    return sys.stdin.isatty()","tryCatchPattern":"from locust.input_events import BaseListener\ntry:\n    listener = GKeyboardListener()\nexcept InitError:\n    listener = None  # no keyboard input in this environment","preventionTips":["Run locust in a real terminal when using interactive keys","Prefer --headless in CI/Docker/services","Allocate a TTY (`docker run -it`) when interaction is needed"],"tags":["terminal","tty","input"],"backgroundTag":"not-a-tty","analyzedSha":"f391a716e12c2c712e80b5835e877b7933397453","analyzedAt":"2026-08-29T00:36:13.872Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}