{"record":{"id":"aef67e0e05d2b5ee","repo":"kovidgoyal/kitty","slug":"could-not-open-controlling-terminal-with-error-w","errorCode":null,"errorMessage":"Could not open controlling terminal with error: %w","messagePattern":"Could not open controlling terminal with error: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tools/cli/wcswidth_kitten.go","lineNumber":221,"sourceCode":"\t\tfor _, grapheme := range t.Data {\n\t\t\tbuf.WriteString(grapheme + cursor_position_report)\n\t\t\tpos += wcswidth.Stringwidth(grapheme)\n\t\t\texpected_cursor_positions = append(expected_cursor_positions, 1+pos)\n\t\t}\n\t\ttest := test_struct{num: len(tests) + 1, description: desc, payload: buf.String(), expected_cursor_positions: expected_cursor_positions}\n\t\ttests = append(tests, &test)\n\t}\n\ttest := test_struct{\n\t\tnum: len(tests) + 1, description: \"Check that combining characters are merged into last cell even when cursor is on the next line\",\n\t\tpayload_gen: wrap_gen, tester: wrap_tester}\n\ttests = append(tests, &test)\n\treturn\n}\n\nfunc main(allowed_tests *utils.Set[int]) (rc int, err error) {\n\tterm, err := tty.OpenControllingTerm()\n\tif err != nil {\n\t\treturn 1, fmt.Errorf(\"Could not open controlling terminal with error: %w\", err)\n\t}\n\tsz, err := term.GetSize()\n\tterm.Close()\n\tif err != nil {\n\t\treturn 1, fmt.Errorf(\"Could not get size of controlling terminal with error: %w\", err)\n\t}\n\twidth_in_cells := int(sz.Col)\n\tif gb_tests, err := kitty.LoadGraphemeBreakTests(); err == nil {\n\t\ttests := create_tests(gb_tests, width_in_cells)\n\t\tif allowed_tests.Len() > 0 {\n\t\t\ttemp := make([]*test_struct, 0, len(tests))\n\t\t\tfor _, t := range tests {\n\t\t\t\tif allowed_tests.Has(t.num) {\n\t\t\t\t\ttemp = append(temp, t)\n\t\t\t\t}\n\t\t\t}\n\t\t\ttests = temp\n\t\t}","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/tools/cli/wcswidth_kitten.go#L203-L239","documentation":"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.","triggerScenarios":"Invoking the kitten in an environment with no controlling terminal: piped stdin/stdout, a cron job, CI, or a pty that has been closed.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if _, err := os.OpenFile(\"/dev/tty\", os.O_RDWR, 0); err != nil { /* abort before running the kitten */ }","typeGuard":null,"tryCatchPattern":"if rc, err := main(allowed); err != nil { fmt.Fprintln(os.Stderr, err); os.Exit(rc) }","preventionTips":["Only run the kitten from interactive terminal sessions","Use ssh -t when running remotely"],"tags":["kitty","tty","terminal"],"backgroundTag":"no-controlling-terminal","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}