charmbracelet/gum · error

stdin is empty

Error message

stdin is empty

What it means

Returned by internal/stdin.Read when IsEmpty() reports that the stdin pipe has no data available. The library requires piped/redirected stdin content and refuses to proceed with empty input rather than blocking or returning an empty string.

Source

Thrown at internal/stdin/stdin.go:39

// StripANSI optionally strips ansi sequences.
func StripANSI(b bool) Option {
	return func(o *options) {
		o.ansiStrip = b
	}
}

// SingleLine reads a single line.
func SingleLine(b bool) Option {
	return func(o *options) {
		o.singleLine = b
	}
}

// Read reads input from an stdin pipe.
func Read(opts ...Option) (string, error) {
	if IsEmpty() {
		return "", fmt.Errorf("stdin is empty")
	}

	options := options{}
	for _, opt := range opts {
		opt(&options)
	}

	reader := bufio.NewReader(os.Stdin)
	var b strings.Builder

	if options.singleLine {
		line, _, err := reader.ReadLine()
		if err != nil {
			return "", fmt.Errorf("failed to read line: %w", err)
		}
		_, err = b.Write(line)
		if err != nil {
			return "", fmt.Errorf("failed to write: %w", err)

View on GitHub (pinned to 4d089f9550)

Solutions

  1. Pipe or redirect content into the command: `cat file | gum pager` or `gum pager < file`
  2. Check the upstream command in the pipeline actually produces output before invoking
  3. If programmatic, verify the reader/write end of the pipe is written and closed properly
  4. Handle the error in your caller and fall back to a file argument instead of stdin

Example fix

// before
out, _ := stdin.Read()  // fails when nothing is piped
// after
out, err := stdin.Read()
if err != nil {
    data, ferr := os.ReadFile("input.txt")
    if ferr == nil { out = string(data) }
}
Defensive patterns

Strategy: validation

Validate before calling

stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) != 0 { return fmt.Errorf("no piped stdin; provide input") }

Type guard

func hasPipedStdin() bool {
    fi, err := os.Stdin.Stat()
    return err == nil && (fi.Mode()&os.ModeCharDevice) == 0
}

Try / catch

out, err := stdin.Read()
if err != nil {
    if err.Error() == "stdin is empty" {
        return fmt.Errorf("please pipe input: cmd | gum pager")
    }
    return err
}

Prevention

When it happens

Trigger: Running the command in a terminal with nothing piped in (stdin is a TTY or an already-drained pipe), or piping an empty file/stream: e.g. `echo -n '' | gum pager` or invoking without `< file`.

Common situations: Forgetting to pipe input in scripts; running interactively where stdin is the TTY; a prior command in the pipeline produced no output (e.g. grep matched nothing).

Related errors


AI-assisted analysis of charmbracelet/gum@4d089f9550 (2026-08-31). Data as JSON: /api/errors/fda20af17073d040. Report an issue: GitHub.