wagoodman/dive · error

failed to set UI: %w

Error message

failed to set UI: %w

What it means

Returned by `dive <image>` when setUI fails to install the v1 gocui UI into the application state (state.UI.Replace(ux)). Identical mechanism to error [7] on the build command: the interactive UI could not be created — usually because stdout is not a usable TTY or the terminal cannot be initialized.

Source

Thrown at cmd/dive/cli/internal/command/root.go:43

func Root(app clio.Application) *cobra.Command {
	opts := &rootOptions{
		Application: options.DefaultApplication(),
	}
	return app.SetupRootCommand(&cobra.Command{
		Use:   "dive [IMAGE]",
		Short: "Docker Image Visualizer & Explorer",
		Long: `This tool provides a way to discover and explore the contents of a docker image. Additionally the tool estimates
the amount of wasted space and identifies the offending files from the image.`,
		Args: func(cmd *cobra.Command, args []string) error {
			if len(args) != 1 {
				return fmt.Errorf("exactly one argument is required")
			}
			opts.Analysis.Image = args[0]
			return nil
		},
		RunE: func(cmd *cobra.Command, _ []string) error {
			if err := setUI(app, opts.Application); err != nil {
				return fmt.Errorf("failed to set UI: %w", err)
			}

			resolver, err := dive.GetImageResolver(opts.Analysis.Source)
			if err != nil {
				return fmt.Errorf("cannot determine image provider to fetch from: %w", err)
			}

			ctx := cmd.Context()

			img, err := adapter.ImageResolver(resolver).Fetch(ctx, opts.Analysis.Image)
			if err != nil {
				return fmt.Errorf("cannot load image: %w", err)
			}

			return run(ctx, opts.Application, img, resolver)
		},
	}, opts)
}

View on GitHub (pinned to d6c691947f)

Solutions

  1. Run in an interactive terminal; for captured environments wrap with script or use a pty
  2. Use non-interactive modes for automation: --ci for gating or --json for data instead of the TUI
  3. export TERM=xterm-256color (and ensure terminfo is installed) in minimal environments
  4. Read the wrapped gocui error for specifics (size, termios failures)

Example fix

# before (CI, no TTY -> UI setup fails)
dive nginx:latest | tee out.txt

# after
dive nginx:latest --json out.json
Defensive patterns

Strategy: validation

Validate before calling

# only start the TUI when stdout is a terminal
[ -t 1 ] && dive myimage:latest || dive myimage:latest --ci

Try / catch

if err := setUI(app, opts.Application); err != nil {
    if !isatty.IsTerminal(os.Stdout.Fd()) {
        // rerun decision: use --ci/--json mode instead of interactive UI
    }
    return fmt.Errorf("failed to set UI: %w", err)
}

Prevention

When it happens

Trigger: Running `dive nginx` with piped/redirected stdout (dive nginx | grep x), from a non-interactive CI shell, through docker exec without -t, or with an invalid/absent TERM variable.

Common situations: Trying to screenshot dive output via pipe; running dive in a cron job or GitLab/GitHub step without a pseudo-TTY; minimal container shells lacking terminfo.

Related errors


AI-assisted analysis of wagoodman/dive@d6c691947f (2026-08-15). Data as JSON: /api/errors/86f17501f1f12fa7. Report an issue: GitHub.