{"record":{"id":"0c39658351b1b652","repo":"kovidgoyal/kitty","slug":"trying-to-send-data-when-to-pipe-is-nil","errorCode":null,"errorMessage":"Trying to send data when to pipe is nil","messagePattern":"Trying to send data when to pipe is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kittens/choose_fonts/backend.go","lineNumber":69,"sourceCode":"\tk.cmd.Stdout = k.w\n\tk.json_decoder = json.NewDecoder(k.from)\n\tif err = k.cmd.Start(); err != nil {\n\t\treturn err\n\t}\n\tk.started = true\n\tk.timeout = 60 * time.Second\n\tk.wait_for_exit = make(chan error)\n\tgo func() {\n\t\tk.wait_for_exit <- k.cmd.Wait()\n\t}()\n\treturn\n}\n\nvar kitty_font_backend kitty_font_backend_type\n\nfunc (k *kitty_font_backend_type) send(v any) error {\n\tif k.to == nil {\n\t\treturn fmt.Errorf(\"Trying to send data when to pipe is nil\")\n\t}\n\tdata, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Could not encode message to kitty with error: %w\", err)\n\t}\n\tc := make(chan error)\n\tgo func() {\n\t\tif _, err = k.to.Write(data); err != nil {\n\t\t\tc <- fmt.Errorf(\"Failed to send message to kitty with I/O error: %w\", err)\n\t\t\treturn\n\t\t}\n\t\tif _, err = k.to.Write([]byte{'\\n'}); err != nil {\n\t\t\tc <- fmt.Errorf(\"Failed to send message to kitty with I/O error: %w\", err)\n\t\t\treturn\n\t\t}\n\t\tc <- nil\n\t}()\n\tselect {","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/choose_fonts/backend.go#L51-L87","documentation":"send() was called on the kitty font backend before its output pipe was established (k.to == nil), i.e. before start() successfully ran or after the backend died and pipes were torn down. It is a programming-order/lifecycle error inside the choose-fonts kitten.","triggerScenarios":"Calling query() -> send() before kitty_font_backend.start() completed os.Pipe(), or after the subprocess exited and pipes were closed.","commonSituations":"Kitty's backend subprocess crashed at startup; race where a query is issued before init finishes; broken kitty installation causing immediate subprocess exit.","solutions":["Ensure start() is called and its error checked before any query()","If the backend crashed, inspect k.stderr for the subprocess error output","Verify the kitty executable works: kitty +runpy 'print(1)'"],"exampleFix":"// before\nkitty_font_backend.send(msg)\n// after\nif err := kitty_font_backend.start(); err != nil { return err }\nkitty_font_backend.send(msg)","handlingStrategy":"type-guard","validationCode":"if kitty_font_backend.to == nil { if err := kitty_font_backend.start(); err != nil { return err } }","typeGuard":"func backendReady(k *kitty_font_backend_type) bool { return k != nil && k.to != nil }","tryCatchPattern":"Check readiness via guard; on send error mentioning nil pipe, call start() and retry once.","preventionTips":["Always start and error-check the backend before issuing queries","Monitor the subprocess and surface its stderr on crash"],"tags":["kitty","pipe","lifecycle","choose-fonts"],"backgroundTag":"pipe-not-initialized","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}