gravitational/teleport · info

canceled

Error message

canceled

What it means

prompt.ErrCanceled is a sentinel error returned when the user selects the quit option in an interactive selection prompt (as opposed to aborting with ctrl-c, which yields ErrInterrupted). Callers are expected to detect it with errors.Is so a deliberate quit is not treated as a system failure.

Source

Thrown at lib/utils/prompt/prompt.go:35

 */

package prompt

import (
	"context"
	"errors"
	"fmt"
	"strings"

	tea "github.com/charmbracelet/bubbletea"
	"github.com/gravitational/trace"
)

// ErrInterrupted is an error when prompt is interrupted with ctrl-c or a signal.
var ErrInterrupted = errors.New("interrupted")

// ErrCanceled is an error when quit option was selected.
var ErrCanceled = errors.New("canceled")

// SelectModel is a generic struct that holds the options, context, and state.
type SelectModel[T any] struct {
	caption     string
	options     []T
	cursor      int
	selected    *T
	renderRow   func(T) string
	quitting    bool
	interrupted bool
}

// NewSelectPrompt initializes the generic model with options, a renderer, and a context.
func NewSelectPrompt[T any](caption string, options []T, renderRow func(T) string) SelectModel[T] {
	if renderRow == nil {
		renderRow = func(t T) string {
			return fmt.Sprintf("%v", t)
		}

View on GitHub (pinned to 1283425b60)

Solutions

  1. Handle it with errors.Is(err, prompt.ErrCanceled) and treat it as a normal, expected exit.
  2. Differentiate from ErrInterrupted if your UX needs distinct messaging for quit vs ctrl-c.
  3. Guard interactive prompts behind an interactivity check (isatty / --non-interactive flag) so prompts are never shown where quitting is the only outcome.

Example fix

// before
result, err := prompt.Run(...)
if err != nil { return err }
// after
result, err := prompt.Run(...)
if err != nil {
  switch {
  case errors.Is(err, prompt.ErrCanceled):
    return nil
  case errors.Is(err, prompt.ErrInterrupted):
    return nil
  }
  return err
}
Defensive patterns

Strategy: type-guard

Type guard

func isPromptCanceled(err error) bool {
    return errors.Is(err, prompt.ErrCanceled)
}

Try / catch

if err != nil {
    if errors.Is(err, prompt.ErrCanceled) {
        return nil // user chose quit
    }
    return trace.Wrap(err)
}

Prevention

When it happens

Trigger: User chooses the quit/cancel entry in a SelectModel-based prompt, causing Run to return trace.Wrap(ErrCanceled).

Common situations: Users backing out of an interactive workflow (e.g. selecting 'quit' in tsh menus); test harnesses simulating the quit selection; confusion with ErrInterrupted since both represent cancellation paths.

Related errors


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/bdf65243cae36972. Report an issue: GitHub.