A terminal froze. The build hung. The cursor blinked like it knew the secret. The problem was a single environment variable: TTY.
Most developers never think about TTY until it breaks something. In Unix-like systems, TTY is short for “teletypewriter,” but in modern engineering, it’s about the virtual terminal interface your process uses. When your scripts or Docker containers expect a terminal and don’t have one, you get strange hangs. When CI jobs try to run interactive commands in a non-interactive shell, TTY is the phantom bottleneck.
The TTY environment variable isn’t always explicitly set. Sometimes it’s implied by the runtime. In Bash or Zsh, you can check it with tty or test -t 0. In CI/CD pipelines, it’s usually absent unless you request allocation with options like --tty in Docker or -t in SSH. The presence or absence changes how output gets buffered and whether prompts can render properly. Get it wrong and builds stall, logging becomes unreliable, or dependencies fail silently.
Inside containers, TTY allocation can alter how your programs behave. Some CLI tools switch modes when they detect an interactive terminal. Without TTY, you might lose color output, progress bars, or prompt input handling. With TTY in the wrong context, you might deadlock automated jobs waiting for input that never comes.