{"record":{"id":"15875c4fa796fcb3","repo":"charmbracelet/bubbletea","slug":"bubbletea-error-restoring-console-w","errorCode":null,"errorMessage":"bubbletea: error restoring console: %w","messagePattern":"bubbletea: error restoring console: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tty.go","lineNumber":44,"sourceCode":"\t\treturn nil\n\t}\n\treturn p.initInput()\n}\n\n// restoreTerminalState restores the terminal to the state prior to running the\n// Bubble Tea program.\nfunc (p *Program) restoreTerminalState() error {\n\t// Flush queued commands.\n\t_ = p.flush()\n\n\treturn p.restoreInput()\n}\n\n// restoreInput restores the tty input to its original state.\nfunc (p *Program) restoreInput() error {\n\tif p.ttyInput != nil && p.previousTtyInputState != nil {\n\t\tif err := term.Restore(p.ttyInput.Fd(), p.previousTtyInputState); err != nil {\n\t\t\treturn fmt.Errorf(\"bubbletea: error restoring console: %w\", err)\n\t\t}\n\t}\n\tif p.ttyOutput != nil && p.previousOutputState != nil {\n\t\tif err := term.Restore(p.ttyOutput.Fd(), p.previousOutputState); err != nil {\n\t\t\treturn fmt.Errorf(\"bubbletea: error restoring console: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// initInputReader (re)commences reading inputs.\nfunc (p *Program) initInputReader(cancel bool) error {\n\tif cancel && p.cancelReader != nil {\n\t\tp.cancelReader.Cancel()\n\t\tp.waitForReadLoop()\n\t}\n\n\tterm := p.environ.Getenv(\"TERM\")","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/charmbracelet/bubbletea/blob/351d2159f8d8a85613aa2a6e98c8c63df3c98623/tty.go#L26-L62","documentation":"Returned by restoreInput (tty.go:44) when term.Restore fails to restore the tty INPUT file descriptor to its previously saved state during shutdown. Bubble Tea saved the termios/Windows-console state when entering raw mode; this error means the terminal was left in raw mode because the ioctl to restore it failed. The wrapped error is usually an ENOTTY/EBADF-class failure indicating the fd or kernel state changed.","triggerScenarios":"The input tty fd was closed before shutdown finished; /dev/tty revoked (vhangup) after SSH detach; program killed with SIGKILL semantics racing restore; a pty whose master side already exited, making tcsetattr return EIO.","commonSituations":"Terminal window closed mid-run; SSH connection dropped before Run's shutdown completed; test ptys torn down while the program restores state; subsequent shell showing raw-mode symptoms (no echo, garbled input) after a crash.","solutions":["If your shell is left in raw mode, run `stty sane` (or `reset`) to fix it immediately","Ensure Program.Run is allowed to finish (don't SIGKILL; use ctx cancel or p.Quit) so restoration completes","Close custom tty files only after Run returns","For ptys in tests, keep the master open until shutdown completes"],"exampleFix":"# after the error, terminal left in raw mode:\n# fix (shell):\nstty sane && reset\n\n// go: ensure orderly shutdown\nctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)\ndefer stop()\np := tea.NewProgram(m, tea.WithContext(ctx))\n_, _ = p.Run() // restoration happens inside Run's shutdown","handlingStrategy":"try-catch","validationCode":"// Before shutdown-heavy runs, confirm the input tty is still restorable:\n// (best effort)\nfunc ttyHealthy(f *os.File) bool {\n    if f == nil { return true }\n    _, _, err := term.GetSize(f.Fd())\n    return err == nil\n}","typeGuard":"func isRestoreFailure(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"bubbletea: error restoring console\")\n}","tryCatchPattern":"_, err := p.Run()\nif isRestoreFailure(err) {\n    fmt.Fprintln(os.Stderr, \"terminal may need `stty sane`; run it if input looks off\")\n    err = nil // non-fatal: program state is still valid\n}","preventionTips":["Always let Run reach its shutdown (avoid SIGKILL on TUIs)","Close tty files only after Run returns","Keep pty masters alive in tests until shutdown completes","Tell users about `stty sane`/`reset` in your README troubleshooting section"],"tags":["bubbletea","tty","termios","restore","shutdown","go"],"backgroundTag":null,"analyzedSha":"351d2159f8d8a85613aa2a6e98c8c63df3c98623","analyzedAt":"2026-08-15T10:48:22.366Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}