sipeed/picoclaw · warning

could not find authorization code in input

Error message

could not find authorization code in input

What it means

The manual input was non-empty but contained no authorization code (oauth.go:179): it had no '?' (so it was treated as a raw code but was blank-ish) or url.Parse found no code query parameter. The user pasted the wrong URL — typically the verification/consent page instead of the post-login localhost redirect.

Source

Thrown at pkg/auth/oauth.go:179

	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")
	}
}

func oauthCallbackRedirectURI(port int) string {
	return fmt.Sprintf("http://localhost:%d/auth/callback", port)
}

func oauthCallbackHandler(state string, resultCh chan<- callbackResult) http.Handler {
	mux := http.NewServeMux()
	mux.HandleFunc("/auth/callback", func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Query().Get("state") != state {
			resultCh <- callbackResult{err: fmt.Errorf("state mismatch")}
			http.Error(w, "State mismatch", http.StatusBadRequest)
			return

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. After granting access in the browser, copy the entire address of the final localhost/auth/callback?... page — it must contain ?code=
  2. If the browser shows 'connection refused' on localhost, that page's URL is still the one to paste
  3. Alternatively paste just the bare code value if your provider shows one
  4. Retry the login flow; the code is single-use and short-lived anyway

Example fix

// before: paste the authorization URL
// https://accounts.example.com/o/oauth2/v2/auth?client_id=...&state=...

// after: paste the post-consent redirect URL
// http://localhost:51121/auth/callback?state=...&code=4/0Ax4Xb...  <- this one
Defensive patterns

Strategy: validation

Validate before calling

// validate manual input before submitting to the flow
func extractCode(input string) (string, error) {
    input = strings.TrimSpace(input)
    if input == "" { return "", fmt.Errorf("empty input") }
    if strings.Contains(input, "?") {
        if u, err := url.Parse(input); err == nil {
            if c := u.Query().Get("code"); c != "" { return c, nil }
        }
        return "", fmt.Errorf("URL has no code= parameter; paste the localhost redirect URL")
    }
    return input, nil // assume bare code
}

Try / catch

if err != nil && strings.Contains(err.Error(), "could not find authorization code") {
    fmt.Println("pasted value lacked ?code= — copy the final http://localhost.../auth/callback?... URL and retry")
    return err
}

Prevention

When it happens

Trigger: Pasting the authorization URL (the one printed for the browser) instead of the resulting redirect; pasting a redirect URL where the provider appended only state and error (denied consent); trailing whitespace/newline making the code extraction fail; pasting a URL whose fragment (#code=) rather than query (?code=) carries the code.

Common situations: First-time users confusing 'open this URL' with 'paste the URL you land on'; providers that redirect with code in the fragment; copy including surrounding log text so '?' branch parses the wrong URL.

Related errors


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