antonmedv/fx · error

<error returned from pipeline p.Run()> (panic(err))

Error message

<error returned from pipeline p.Run()> (panic(err))

What it means

main runs the interactive pipeline via p.Run() and panics if the pipeline returns an error. All normal errors (parse errors, expression errors) are expected to be carried elsewhere (e.g. m.printErrorOnExit); an error reaching this point indicates an unexpected pipeline failure such as a terminal setup fault or an internal state violation.

Source

Thrown at main.go:326

					p.Send(errorMsg{err: err})
					break
				}
				textNode := parser.Recover()
				if !firstOk && !strings.HasPrefix(textNode.Value, "HTTP") {
					p.Send(errorMsg{err: err})
					break
				}
				p.Send(nodeMsg{node: textNode})
			} else {
				firstOk = true
				p.Send(nodeMsg{node: node})
			}
		}
	}()

	_, err := p.Run()
	if err != nil {
		panic(err)
	}

	if m.printErrorOnExit != nil {
		fmt.Println(m.printErrorOnExit.Error())
	} else if m.printOnExit {
		fmt.Println(m.cursorValue())
	} else {
		exit()
	}
}

type model struct {
	termWidth, termHeight int
	head, top, bottom     *Node
	eof                   bool
	cursor                int // cursor position [0, termHeight)
	suspending            bool
	showCursor            bool

View on GitHub (pinned to 4f31cd3a0c)

Solutions

  1. Run fx in an interactive terminal (allocate a TTY: docker run -t, ssh -t)
  2. Set TERM to a supported value (e.g. xterm-256color) or unset TERM=dumb
  3. Use non-interactive mode (pipe output, no TTY usage) when a TTY is unavailable
  4. Check the wrapped error message for the specific terminal subsystem failure and update the terminal library if it's a known bug

Example fix

// before
_, err := p.Run()
if err != nil {
	panic(err)
}
// after
_, err := p.Run()
if err != nil {
	fmt.Fprintf(os.Stderr, "interactive mode failed: %v\n", err)
	os.Exit(1)
}
Defensive patterns

Strategy: fallback

Validate before calling

// detect TTY availability before running interactive mode
if term.IsTerminal(int(os.Stdin.Fd())) == false && mode == interactive {
	// fall back to non-interactive processing
}

Try / catch

// recover around pipeline execution
_, err := func() (out any, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("pipeline panicked: %v", r)
		}
	}()
	return p.Run()
}()

Prevention

When it happens

Trigger: p.Run() returns a non-nil error — typically a bubbletea/termenv-style terminal failure: failure to open /dev/tty, unsupported TERM, or an unrecovered renderer panic surfaced as an error.

Common situations: Running fx in an environment without a TTY (CI, non-interactive SSH, docker run without -t); TERM set to 'dumb' or unset; terminal too small or terminfo missing.

Related errors


AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02). Data as JSON: /api/errors/7315d9c42f5c9950. Report an issue: GitHub.