{"record":{"id":"80943f81345707db","repo":"sipeed/picoclaw","slug":"no-input-received","errorCode":null,"errorMessage":"no input received","messagePattern":"no input received","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/auth/token.go","lineNumber":19,"sourceCode":"package auth\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\nfunc LoginPasteToken(provider string, r io.Reader) (*AuthCredential, error) {\n\tfmt.Printf(\"Paste your API key or session token from %s:\\n\", providerDisplayName(provider))\n\tfmt.Print(\"> \")\n\n\tscanner := bufio.NewScanner(r)\n\tif !scanner.Scan() {\n\t\tif err := scanner.Err(); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"reading token: %w\", err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"no input received\")\n\t}\n\n\ttoken := strings.TrimSpace(scanner.Text())\n\tif token == \"\" {\n\t\treturn nil, fmt.Errorf(\"token cannot be empty\")\n\t}\n\n\treturn &AuthCredential{\n\t\tAccessToken: token,\n\t\tProvider:    provider,\n\t\tAuthMethod:  \"token\",\n\t}, nil\n}\n\nfunc LoginSetupToken(r io.Reader) (*AuthCredential, error) {\n\tfmt.Println(\"Paste your setup token from `claude setup-token`:\")\n\tfmt.Print(\"> \")\n","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/auth/token.go#L1-L37","documentation":"LoginPasteToken (pkg/auth/token.go:19) saw scanner.Scan() return false with a nil error, meaning clean EOF: the reader produced no line at all. Nothing was typed or piped in — the prompt got an immediately-closed or empty stream rather than a too-long or broken one (those are separate errors).","triggerScenarios":"Running LoginPasteToken in a non-interactive context where stdin is closed or empty: /dev/null, an empty pipe, a CI job with no TTY, or the user pressing Ctrl-D immediately at the '> ' prompt.","commonSituations":"Auth prompt invoked in CI/scripts where stdin is not attached; user hits Ctrl-D instead of pasting; automation calling the CLI without wiring stdin; piping an empty file (e.g. `cli login < /dev/null`).","solutions":["Ensure stdin is attached and interactive when calling the login prompt, or run it in a real terminal","In scripts, feed the token directly: LoginPasteToken(provider, strings.NewReader(token)) — a reader with content never EOFs empty","If interactive, instruct the user that Ctrl-D aborts; they must paste a line then press Enter","Detect TTY first and fail fast with a clearer message (e.g. suggest a non-interactive flag)"],"exampleFix":"// before\ncred, err := auth.LoginPasteToken(provider, os.Stdin)\n\n// after (non-interactive path feeds the token directly)\nvar r io.Reader = os.Stdin\nif token != \"\" {\n\tr = strings.NewReader(token)\n}\ncred, err := auth.LoginPasteToken(provider, r)","handlingStrategy":"validation","validationCode":"// For scripted use, never rely on interactive stdin\nif term.IsTerminal(int(os.Stdin.Fd())) {\n\tcred, err := auth.LoginPasteToken(provider, os.Stdin)\n} else if tokenEnv := strings.TrimSpace(os.Getenv(\"API_TOKEN\")); tokenEnv != \"\" {\n\tcred, err := auth.LoginPasteToken(provider, strings.NewReader(tokenEnv))\n} else {\n\treturn fmt.Errorf(\"no interactive terminal and no API_TOKEN set\")\n}","typeGuard":"func isNoInputError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"no input received\")\n}","tryCatchPattern":"cred, err := auth.LoginPasteToken(provider, r)\nif err != nil && isNoInputError(err) {\n\t// EOF on stdin: prompt again or switch to a non-interactive token source\n\treturn promptOrEnvFallback()\n}","preventionTips":["Detect TTY before showing an interactive prompt","Wire non-interactive token sources (env var, file) in CI","Educate users that Ctrl-D aborts the prompt","Retry the prompt once on plain EOF — users often hit Enter/Ctrl-D accidentally"],"tags":["input","stdin","eof","cli","token","go"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}