{"record":{"id":"d15303113fdb15b8","repo":"restic/restic","slug":"write-failed-w","errorCode":null,"errorMessage":"write failed: %w","messagePattern":"write failed: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/terminal/terminal_posix.go","lineNumber":26,"sourceCode":"\nconst (\n\t// PosixControlMoveCursorHome moves cursor to the first column\n\tPosixControlMoveCursorHome = \"\\r\"\n\t// PosixControlMoveCursorUp moves cursor up one line\n\tPosixControlMoveCursorUp = \"\\x1b[1A\"\n\t// PosixControlMoveCursorDown moves cursor down one line\n\tPosixControlMoveCursorDown = \"\\x1b[1B\"\n\t// PosixControlClearLine clears the current line\n\tPosixControlClearLine = \"\\x1b[2K\"\n)\n\n// PosixClearCurrentLine removes all characters from the current line and resets the\n// cursor position to the first column.\nfunc PosixClearCurrentLine(wr io.Writer, _ uintptr) error {\n\t// clear current line\n\t_, err := wr.Write([]byte(PosixControlMoveCursorHome + PosixControlClearLine))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write failed: %w\", err)\n\t}\n\treturn nil\n}\n\n// PosixMoveCursorUp moves the cursor to the line n lines above the current one.\nfunc PosixMoveCursorUp(wr io.Writer, _ uintptr, n int) error {\n\tdata := []byte(PosixControlMoveCursorHome)\n\tdata = append(data, bytes.Repeat([]byte(PosixControlMoveCursorUp), n)...)\n\t_, err := wr.Write(data)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write failed: %w\", err)\n\t}\n\treturn nil\n}\n\n// PosixMoveCursorDown moves the cursor to the line n lines below the current one.\nfunc PosixMoveCursorDown(wr io.Writer, _ uintptr, n int) error {\n\tdata := []byte(PosixControlMoveCursorHome)","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/restic/restic/blob/a80be1478a4c537f8396e0db2b05120aa78f11e0/internal/terminal/terminal_posix.go#L8-L44","documentation":"PosixClearCurrentLine failed to write its ANSI escape sequence (cursor-home + clear-line) to the progress-display writer. This is status-line cosmetics for interactive terminals; the wrapped error is virtually always EPIPE (reader gone) or ENOSPC/EIO when output is redirected.","triggerScenarios":"restic's stdout is piped into a program that exits early (head, grep -m1) so writes hit a closed pipe; output redirected to a file on a full disk; terminal window closed while a long operation renders progress.","commonSituations":"Piping restic through head in scripts; killing the pager but not restic; /tmp or log volume full when redirecting; CI capturing output with small buffers that close early.","solutions":["Keep the downstream reader alive for the whole run, or redirect to a file instead of a pipe","Free disk space when redirecting to a full filesystem","Use --json (or quiet mode) in scripts to disable in-place status rendering entirely","Treat it as non-fatal if your own tooling consumed enough output — the backup itself usually continues"],"exampleFix":"# before\nrestic backup /data | head -5\n# Error: write failed: broken pipe\n\n# after (file redirect or quiet mode in scripts)\nrestic backup /data --quiet >> /var/log/restic.log 2>&1","handlingStrategy":"try-catch","validationCode":"// only render interactive status when the writer is a real terminal\nif term.IsTerminal(int(os.Stdout.Fd())) {\n    _ = terminal.PosixClearCurrentLine(os.Stdout, fd)\n}","typeGuard":null,"tryCatchPattern":"if err := terminal.PosixClearCurrentLine(w, fd); err != nil {\n    if errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ENOSPC) {\n        return // cosmetic: drop progress rendering, keep the operation running\n    }\n    return err\n}","preventionTips":["Use --quiet or --json for any scripted/piped invocation","Redirect logs to files, not to early-exiting pipes like head","Register signal handling to ignore SIGPIPE for status writes"],"tags":["go","restic","terminal","progress","epipe"],"backgroundTag":null,"analyzedSha":"a80be1478a4c537f8396e0db2b05120aa78f11e0","analyzedAt":"2026-08-15T15:30:29.928Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}