kovidgoyal/kitty · error
Could not open controlling terminal with error: %w
Error message
Could not open controlling terminal with error: %w
What it means
The wcswidth kitten could not open the controlling terminal (tty.OpenControllingTerm failed). It needs direct tty access to write test sequences and read cursor position reports, so without it the kitten cannot run.
Source
Thrown at tools/cli/wcswidth_kitten.go:221
for _, grapheme := range t.Data {
buf.WriteString(grapheme + cursor_position_report)
pos += wcswidth.Stringwidth(grapheme)
expected_cursor_positions = append(expected_cursor_positions, 1+pos)
}
test := test_struct{num: len(tests) + 1, description: desc, payload: buf.String(), expected_cursor_positions: expected_cursor_positions}
tests = append(tests, &test)
}
test := test_struct{
num: len(tests) + 1, description: "Check that combining characters are merged into last cell even when cursor is on the next line",
payload_gen: wrap_gen, tester: wrap_tester}
tests = append(tests, &test)
return
}
func main(allowed_tests *utils.Set[int]) (rc int, err error) {
term, err := tty.OpenControllingTerm()
if err != nil {
return 1, fmt.Errorf("Could not open controlling terminal with error: %w", err)
}
sz, err := term.GetSize()
term.Close()
if err != nil {
return 1, fmt.Errorf("Could not get size of controlling terminal with error: %w", err)
}
width_in_cells := int(sz.Col)
if gb_tests, err := kitty.LoadGraphemeBreakTests(); err == nil {
tests := create_tests(gb_tests, width_in_cells)
if allowed_tests.Len() > 0 {
temp := make([]*test_struct, 0, len(tests))
for _, t := range tests {
if allowed_tests.Has(t.num) {
temp = append(temp, t)
}
}
tests = temp
}View on GitHub (pinned to 6d5d0c4406)
Solutions
- Run the command from an interactive terminal session
- If over ssh, use 'ssh -t' to force pty allocation
- Avoid redirecting stdin/stdout of the kitten
- Run it inside the kitty terminal itself
Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.OpenFile("/dev/tty", os.O_RDWR, 0); err != nil { /* abort before running the kitten */ } Try / catch
if rc, err := main(allowed); err != nil { fmt.Fprintln(os.Stderr, err); os.Exit(rc) } Prevention
- Only run the kitten from interactive terminal sessions
- Use ssh -t when running remotely
When it happens
Trigger: Invoking the kitten in an environment with no controlling terminal: piped stdin/stdout, a cron job, CI, or a pty that has been closed.
Common situations: Running kitty +kitten wcswidth via ssh with no tty allocation (missing -t), redirecting output to a file, running from a script without a terminal, or executing inside CI containers.
Related errors
- Failed to open controlling terminal with error: %w
- Unknown marker type: {ftype}
- {rest} is not a valid marker specification
- {rest} is not a valid scroll_to_mark destination
- {name} is not a valid color
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/aef67e0e05d2b5ee.
Report an issue: GitHub.