kovidgoyal/kitty · error

Failed to read from STDIN pipe with error: %w

Error message

Failed to read from STDIN pipe with error: %w

What it means

The clipboard kitten prereads STDIN (up to 2MB) before interacting with the terminal. If reading os.Stdin fails with something other than the too-much-data sentinel, this wrapped error is returned. It usually means the pipe was broken or closed prematurely.

Source

Thrown at kittens/clipboard/legacy.go:77

			if err == io.EOF {
				err = nil
			}
			return b, err
		}
	}
}

func preread_stdin() (data_src io.Reader, tempfile *os.File, err error) {
	// we pre-read STDIN because otherwise if the output of a command is being piped in
	// and that command itself transmits on the tty we will break. For example
	// kitten @ ls | kitten clipboard
	var stdin_data []byte
	stdin_data, err = read_all_with_max_size(os.Stdin, 2*1024*1024)
	if err == nil {
		os.Stdin.Close()
	} else if err != ErrTooMuchPipedData {
		os.Stdin.Close()
		err = fmt.Errorf("Failed to read from STDIN pipe with error: %w", err)
		return
	}
	if err == ErrTooMuchPipedData {
		tempfile, err = utils.CreateAnonymousTemp("")
		if err != nil {
			return nil, nil, fmt.Errorf("Failed to create a temporary from STDIN pipe with error: %w", err)
		}
		tempfile.Write(stdin_data)
		_, err = io.Copy(tempfile, os.Stdin)
		os.Stdin.Close()
		if err != nil {
			return nil, nil, fmt.Errorf("Failed to copy data from STDIN pipe to temp file with error: %w", err)
		}
		tempfile.Seek(0, io.SeekStart)
		data_src = tempfile
	} else if stdin_data != nil {
		data_src = bytes.NewBuffer(stdin_data)
	}

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Check the upstream command in the pipeline actually succeeds
  2. Retry the pipeline ensuring the writer keeps STDIN open until done
  3. Inspect the wrapped %w error for the real OS cause (EPIPE, EBADF)
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the producer keeps stdin open, e.g. with a fifo held open

Try / catch

data, tf, err := preread_stdin()
if err != nil { return fmt.Errorf("reading stdin: %w", err) } // inspect wrapped errors.Error() for EPIPE

Prevention

When it happens

Trigger: Piping from a process that exits/closes the pipe early, e.g. 'echo foo | kitty +kitten clipboard' where the writer fails, or STDIN redirected to a closed fd.

Common situations: Broken pipe from an upstream command crash, piping from a process killed by a signal, or running with STDIN closed (</dev/null is fine since read succeeds).

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/c4ff5bafed6f23a6. Report an issue: GitHub.