router-for-me/CLIProxyAPI · warning

Method not allowed

Error message

Method not allowed

What it means

The Codex OAuth callback HTTP handler only accepts GET. Any other method (POST, HEAD, PUT, DELETE) receives a 405 with body "Method not allowed" and no OAuthResult is delivered to the waiting code exchange.

Source

Thrown at internal/auth/codex/oauth_server.go:170

		return nil, err
	case <-time.After(timeout):
		return nil, fmt.Errorf("timeout waiting for OAuth callback")
	}
}

// handleCallback handles the OAuth callback endpoint.
// It extracts the authorization code and state from the callback URL,
// validates the parameters, and sends the result to the waiting channel.
//
// Parameters:
//   - w: The HTTP response writer
//   - r: The HTTP request
func (s *OAuthServer) handleCallback(w http.ResponseWriter, r *http.Request) {
	log.Debug("Received OAuth callback")

	// Validate request method
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	// Extract parameters
	query := r.URL.Query()
	code := query.Get("code")
	state := query.Get("state")
	errorParam := query.Get("error")

	// Validate required parameters
	if errorParam != "" {
		log.Errorf("OAuth error received: %s", errorParam)
		result := &OAuthResult{
			Error: errorParam,
		}
		s.sendResult(result)
		http.Error(w, fmt.Sprintf("OAuth error: %s", errorParam), http.StatusBadRequest)
		return

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Ensure the callback arrives as a browser GET redirect (default query response mode)
  2. Test with plain curl (GET): curl "http://127.0.0.1:PORT/callback?code=x&state=y"
  3. Disable form_post response mode on the IdP for this client

Example fix

# before
curl -X POST "http://127.0.0.1:1455/auth/callback?code=abc&state=xyz"
# 405 Method not allowed

# after
curl "http://127.0.0.1:1455/auth/callback?code=abc&state=xyz"
Defensive patterns

Strategy: validation

Validate before calling

if r.Method != http.MethodGet {
    w.Header().Set("Allow", http.MethodGet)
    http.Error(w, "GET only", http.StatusMethodNotAllowed)
    return
}
// when probing the Codex callback manually, always use GET

Type guard

func isGet(r *http.Request) bool { return r.Method == http.MethodGet }

Try / catch

result, err := server.WaitForCode(ctx)
if err != nil || result.Error != "" { log.Printf("codex oauth failed: %v %s", err, result.Error) }

Prevention

When it happens

Trigger: POST to the Codex callback route (e.g. response_mode=form_post from the IdP), a HEAD health-check probe, or scripted tests using the wrong verb.

Common situations: Identity providers converting redirects into form posts; monitoring probes hitting the loopback callback port during login; curl invocations with -X POST copied from other examples.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/e6ccc5012d50aae6. Report an issue: GitHub.