{"record":{"id":"1a07a23af30ca1c9","repo":"sipeed/picoclaw","slug":"no-selection-provided","errorCode":null,"errorMessage":"no selection provided","messagePattern":"no selection provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/model/add.go","lineNumber":137,"sourceCode":"\nfunc pickModel(stdin io.Reader, stdout io.Writer, entries []modelEntry) (string, error) {\n\tfmt.Fprintf(stdout, \"\\n%d model(s) available:\\n\", len(entries))\n\tfor i, m := range entries {\n\t\tline := m.ID\n\t\tif m.Name != \"\" && m.Name != m.ID {\n\t\t\tline = fmt.Sprintf(\"%s (%s)\", m.ID, m.Name)\n\t\t}\n\t\tfmt.Fprintf(stdout, \"  %3d) %s\\n\", i+1, line)\n\t}\n\n\tscanner := bufio.NewScanner(stdin)\n\tfor {\n\t\tfmt.Fprint(stdout, \"Pick a model (number or id): \")\n\t\tif !scanner.Scan() {\n\t\t\tif err := scanner.Err(); err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"read input: %w\", err)\n\t\t\t}\n\t\t\treturn \"\", fmt.Errorf(\"no selection provided\")\n\t\t}\n\t\ttext := strings.TrimSpace(scanner.Text())\n\t\tif text == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif idx, err := strconv.Atoi(text); err == nil {\n\t\t\tif idx < 1 || idx > len(entries) {\n\t\t\t\tfmt.Fprintf(stdout, \"Out of range. Enter 1-%d.\\n\", len(entries))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn entries[idx-1].ID, nil\n\t\t}\n\t\tfor _, m := range entries {\n\t\t\tif m.ID == text {\n\t\t\t\treturn m.ID, nil\n\t\t\t}\n\t\t}\n\t\tfmt.Fprintln(stdout, \"Not a valid number or model id; try again.\")","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/model/add.go#L119-L155","documentation":"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).","triggerScenarios":"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.","commonSituations":"Automated environments invoking the interactive command without flags; users pressing Ctrl-D instead of Ctrl-C to abort; here-docs that supply no line.","solutions":["Provide the model id up front: picoclaw model add -m <model-id>","Or supply the selection on stdin: printf '2\\n' | picoclaw model add -b <base> -k <key>","Interactively, just type a number or model id and press Enter"],"exampleFix":"# before\n$ picoclaw model add -b <base> -k <key>\nPick a model (number or id): ^D\nno selection provided\n\n# after\n$ picoclaw model add -b <base> -k <key> -m kimi-k2-250711","handlingStrategy":"validation","validationCode":"if modelID == \"\" {\n  fi, err := os.Stdin.Stat()\n  if err != nil || fi.Size() == 0 && fi.Mode()&os.ModeCharDevice == 0 {\n    return fmt.Errorf(\"stdin has no input; pass -m <model-id> or pipe a selection\")\n  }\n}","typeGuard":"func isNoSelectionError(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"no selection provided\")\n}","tryCatchPattern":"if err := runAdd(opt); err != nil {\n  if isNoSelectionError(err) {\n    // EOF before any choice: fall back to re-running with -m <first-listed-model>\n  }\n  return err\n}","preventionTips":["Pass -m <model-id> in every scripted invocation","When piping selections, always end with a newline: printf '2\\n' | picoclaw model add ...","Use Ctrl-C, not Ctrl-D, to abort the prompt if you plan to retry"],"tags":["cli","model","stdin","eof"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}