sipeed/picoclaw · error

no selection provided

Error message

no selection provided

What it means

The interactive model picker hit clean EOF on stdin — Scanner.Scan() returned false with no I/O error — before any selection was made. In a terminal this is what Ctrl-D produces; in scripts it means stdin was exhausted or empty while -m/--model was omitted (a model id skips the prompt entirely).

Source

Thrown at cmd/picoclaw/internal/model/add.go:137

func pickModel(stdin io.Reader, stdout io.Writer, entries []modelEntry) (string, error) {
	fmt.Fprintf(stdout, "\n%d model(s) available:\n", len(entries))
	for i, m := range entries {
		line := m.ID
		if m.Name != "" && m.Name != m.ID {
			line = fmt.Sprintf("%s (%s)", m.ID, m.Name)
		}
		fmt.Fprintf(stdout, "  %3d) %s\n", i+1, line)
	}

	scanner := bufio.NewScanner(stdin)
	for {
		fmt.Fprint(stdout, "Pick a model (number or id): ")
		if !scanner.Scan() {
			if err := scanner.Err(); err != nil {
				return "", fmt.Errorf("read input: %w", err)
			}
			return "", fmt.Errorf("no selection provided")
		}
		text := strings.TrimSpace(scanner.Text())
		if text == "" {
			continue
		}
		if idx, err := strconv.Atoi(text); err == nil {
			if idx < 1 || idx > len(entries) {
				fmt.Fprintf(stdout, "Out of range. Enter 1-%d.\n", len(entries))
				continue
			}
			return entries[idx-1].ID, nil
		}
		for _, m := range entries {
			if m.ID == text {
				return m.ID, nil
			}
		}
		fmt.Fprintln(stdout, "Not a valid number or model id; try again.")

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Provide the model id up front: picoclaw model add -m <model-id>
  2. Or supply the selection on stdin: printf '2\n' | picoclaw model add -b <base> -k <key>
  3. Interactively, just type a number or model id and press Enter

Example fix

# before
$ picoclaw model add -b <base> -k <key>
Pick a model (number or id): ^D
no selection provided

# after
$ picoclaw model add -b <base> -k <key> -m kimi-k2-250711
Defensive patterns

Strategy: validation

Validate before calling

if modelID == "" {
  fi, err := os.Stdin.Stat()
  if err != nil || fi.Size() == 0 && fi.Mode()&os.ModeCharDevice == 0 {
    return fmt.Errorf("stdin has no input; pass -m <model-id> or pipe a selection")
  }
}

Type guard

func isNoSelectionError(err error) bool {
  return err != nil && strings.Contains(err.Error(), "no selection provided")
}

Try / catch

if err := runAdd(opt); err != nil {
  if isNoSelectionError(err) {
    // EOF before any choice: fall back to re-running with -m <first-listed-model>
  }
  return err
}

Prevention

When it happens

Trigger: Pressing Ctrl-D at the 'Pick a model (number or id):' prompt; piping empty input (echo -n '' | picoclaw model add); running non-interactively in CI/cron with no stdin attached and no -m flag.

Common situations: Automated environments invoking the interactive command without flags; users pressing Ctrl-D instead of Ctrl-C to abort; here-docs that supply no line.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/1a07a23af30ca1c9. Report an issue: GitHub.