sipeed/picoclaw · warning

no input received

Error message

no input received

What it means

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).

Source

Thrown at pkg/auth/token.go:19

package auth

import (
	"bufio"
	"fmt"
	"io"
	"strings"
)

func LoginPasteToken(provider string, r io.Reader) (*AuthCredential, error) {
	fmt.Printf("Paste your API key or session token from %s:\n", providerDisplayName(provider))
	fmt.Print("> ")

	scanner := bufio.NewScanner(r)
	if !scanner.Scan() {
		if err := scanner.Err(); err != nil {
			return nil, fmt.Errorf("reading token: %w", err)
		}
		return nil, fmt.Errorf("no input received")
	}

	token := strings.TrimSpace(scanner.Text())
	if token == "" {
		return nil, fmt.Errorf("token cannot be empty")
	}

	return &AuthCredential{
		AccessToken: token,
		Provider:    provider,
		AuthMethod:  "token",
	}, nil
}

func LoginSetupToken(r io.Reader) (*AuthCredential, error) {
	fmt.Println("Paste your setup token from `claude setup-token`:")
	fmt.Print("> ")

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Ensure stdin is attached and interactive when calling the login prompt, or run it in a real terminal
  2. In scripts, feed the token directly: LoginPasteToken(provider, strings.NewReader(token)) — a reader with content never EOFs empty
  3. If interactive, instruct the user that Ctrl-D aborts; they must paste a line then press Enter
  4. Detect TTY first and fail fast with a clearer message (e.g. suggest a non-interactive flag)

Example fix

// before
cred, err := auth.LoginPasteToken(provider, os.Stdin)

// after (non-interactive path feeds the token directly)
var r io.Reader = os.Stdin
if token != "" {
	r = strings.NewReader(token)
}
cred, err := auth.LoginPasteToken(provider, r)
Defensive patterns

Strategy: validation

Validate before calling

// For scripted use, never rely on interactive stdin
if term.IsTerminal(int(os.Stdin.Fd())) {
	cred, err := auth.LoginPasteToken(provider, os.Stdin)
} else if tokenEnv := strings.TrimSpace(os.Getenv("API_TOKEN")); tokenEnv != "" {
	cred, err := auth.LoginPasteToken(provider, strings.NewReader(tokenEnv))
} else {
	return fmt.Errorf("no interactive terminal and no API_TOKEN set")
}

Type guard

func isNoInputError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "no input received")
}

Try / catch

cred, err := auth.LoginPasteToken(provider, r)
if err != nil && isNoInputError(err) {
	// EOF on stdin: prompt again or switch to a non-interactive token source
	return promptOrEnvFallback()
}

Prevention

When it happens

Trigger: 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.

Common situations: 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`).

Related errors


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