sipeed/picoclaw · warning

manual input canceled

Error message

manual input canceled

What it means

The manual-input fallback path (oauth.go:168) received an empty string: the user dismissed or submitted nothing at the paste-the-redirect-URL prompt while the browser callback never arrived. It is a user-abort signal, not a system fault — the login simply has no code to exchange.

Source

Thrown at pkg/auth/oauth.go:168

	defer close(manualDone)
	go func() {
		reader := bufio.NewReader(browserLoginInput)
		input, _ := reader.ReadString('\n')
		select {
		case manualCh <- strings.TrimSpace(input):
		case <-manualDone:
		}
	}()

	select {
	case result := <-resultCh:
		if result.err != nil {
			return nil, result.err
		}
		return ExchangeCodeForTokens(cfg, result.code, pkce.CodeVerifier, redirectURI)
	case manualInput := <-manualCh:
		if manualInput == "" {
			return nil, fmt.Errorf("manual input canceled")
		}
		// Extract code from URL if it's a full URL
		code := manualInput
		if strings.Contains(manualInput, "?") {
			u, err := url.Parse(manualInput)
			if err == nil {
				code = u.Query().Get("code")
			}
		}
		if code == "" {
			return nil, fmt.Errorf("could not find authorization code in input")
		}
		return ExchangeCodeForTokens(cfg, code, pkce.CodeVerifier, redirectURI)
	case <-time.After(5 * time.Minute):
		return nil, fmt.Errorf("authentication timed out after 5 minutes")
	}
}

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Re-run the login command and complete it
  2. Paste the full localhost callback URL (it contains ?code=...) instead of submitting empty
  3. If the browser cannot open (no GUI), make sure to copy the printed auth URL into a browser on another machine and bring back the redirect URL
  4. Use the device-code flow (RequestDeviceCode) when paste-back is awkward
Defensive patterns

Strategy: validation

Validate before calling

// at the CLI layer around the manual prompt
input := strings.TrimSpace(readLine())
if input == "" {
    fmt.Println("no input given — aborting login; re-run and paste the redirect URL")
    return errAbort
}

Try / catch

if err != nil && strings.Contains(err.Error(), "manual input canceled") {
    // user aborted: guide, don't crash
    fmt.Println("login canceled — run the login command again and paste the localhost callback URL")
    return nil
}

Prevention

When it happens

Trigger: User hits Enter on an empty prompt or cancels the terminal read (EOF) in the NoBrowser/manual flow before the browser redirect lands anywhere.

Common situations: Headless/SSH sessions using the manual flow; user realizes the browser never opened and aborts; paste of whitespace-only input.

Related errors


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