{"record":{"id":"86c49dbeca78b487","repo":"charmbracelet/bubbletea","slug":"bubbletea-error-writing-insert-above-to-the-write","errorCode":null,"errorMessage":"bubbletea: error writing insert above to the writer: %w","messagePattern":"bubbletea: error writing insert above to the writer: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cursed_renderer.go","lineNumber":759,"sourceCode":"\t// on the cursor position.\n\tup := offset + h - 1\n\tsb.WriteString(ansi.CursorUp(up))\n\tsb.WriteString(ansi.InsertLine(offset))\n\tfor _, line := range lines {\n\t\tsb.WriteString(line)\n\t\tsb.WriteString(ansi.EraseLineRight)\n\t\tsb.WriteString(\"\\r\\n\")\n\t}\n\n\ts.scr.SetPosition(0, 0)\n\n\tif s.logger != nil {\n\t\ts.logger.Printf(\"insert above: %q\", sb.String())\n\t}\n\n\t_, err := io.WriteString(s.w, sb.String())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"bubbletea: error writing insert above to the writer: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// onMouse implements renderer.\nfunc (s *cursedRenderer) onMouse(m MouseMsg) Cmd {\n\tvar onMouse func(MouseMsg) Cmd\n\ts.mu.Lock()\n\tif s.lastView != nil {\n\t\tonMouse = s.lastView.OnMouse\n\t}\n\ts.mu.Unlock()\n\tif onMouse != nil {\n\t\treturn onMouse(m)\n\t}\n\treturn nil\n}","sourceCodeStart":741,"sourceCodeEnd":777,"githubUrl":"https://github.com/charmbracelet/bubbletea/blob/351d2159f8d8a85613aa2a6e98c8c63df3c98623/cursed_renderer.go#L741-L777","documentation":"Returned by the renderer's insertAbove path (used by tea.ScrollUp / SyncScrollArea-style output above the frame) when writing the pre-built scrollback lines to the output writer fails. Unlike normal frames, this content bypasses the screen diff and is written directly, so a writer failure here loses scrollback lines permanently. The error wraps the underlying io.WriteString failure.","triggerScenarios":"Calling tea.ScrollUpCmd / rendering content above the frame while the output writer is closed or broken; inserting log lines above the TUI when stdout is a dead pipe; pty torn down during scrollback emission.","commonSituations":"Apps that print log lines above the UI (ScrollUp) running with redirected output; terminal closed right as a burst of above-frame messages is emitted; custom writers that fail intermittently under load.","solutions":["Verify the writer used with tea.WithOutput is open before issuing scroll-up commands","Rate-limit or buffer insert-above output for flaky writers","Handle EPIPE/ErrClosed by quitting the program instead of continuing to scroll","Reproduce with a bytes.Buffer writer in tests to rule out writer-side bugs"],"exampleFix":"// before\nfunc (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {\n    return m, tea.ScrollUpCmd(lines) // fails when output is broken\n}\n\n// after\nfunc (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {\n    if m.outputOK {\n        return m, tea.ScrollUpCmd(lines)\n    }\n    return m, tea.Quit\n}","handlingStrategy":"validation","validationCode":"// Before issuing insert-above, confirm output health:\nfunc canScrollAbove(w io.Writer) bool {\n    _, err := w.Write(nil)\n    return err == nil\n}","typeGuard":"func isInsertAboveFailure(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"error writing insert above to the writer\")\n}","tryCatchPattern":"if err := tea.NewProgram(m).Run(); isInsertAboveFailure(err) {\n    if isDeadPipe(errors.Unwrap(errors.Unwrap(err))) {\n        os.Exit(0)\n    }\n    log.Fatal(err)\n}","preventionTips":["Batch ScrollUp calls instead of one write per line under flaky writers","Check writer health before emitting log storms above the frame","Route logs to a file (LogToFile) rather than insert-above on fragile transports"],"tags":["bubbletea","scrollback","insert-above","io","go"],"backgroundTag":null,"analyzedSha":"351d2159f8d8a85613aa2a6e98c8c63df3c98623","analyzedAt":"2026-08-15T10:48:22.366Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}