chenhg5/cc-connect · error

POST only

Error message

POST only

What it means

The webhook endpoint only accepts HTTP POST. Any request with a different method (GET, PUT, DELETE, etc.) is rejected with 405 and body "POST only" before authentication is even attempted. This enforces the webhook contract, since payloads are carried in the POST body.

Source

Thrown at core/webhook.go:88

	go func() {
		slog.Info("webhook: server started", "addr", addr, "path", ws.path)
		if err := ws.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			slog.Error("webhook: server error", "error", err)
		}
	}()
}

func (ws *WebhookServer) Stop() {
	if ws.server != nil {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		_ = ws.server.Shutdown(ctx)
	}
}

func (ws *WebhookServer) handleHook(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "POST only", http.StatusMethodNotAllowed)
		return
	}

	if !ws.authenticate(r) {
		http.Error(w, "unauthorized", http.StatusUnauthorized)
		return
	}

	var req WebhookRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "invalid JSON: "+err.Error(), http.StatusBadRequest)
		return
	}

	if req.SessionKey == "" {
		http.Error(w, "session_key is required", http.StatusBadRequest)
		return
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Change the request method to POST.
  2. For health checks, configure the monitor to expect 405 or use a dedicated health endpoint.
  3. If the sender is a framework defaulting to another method, explicitly set method: 'POST'.

Example fix

// before
fetch(url)
// after
fetch(url, { method: "POST", headers: {"Authorization": "Bearer <token>", "Content-Type": "application/json"}, body: JSON.stringify({session_key: "s1", prompt: "hi"}) })
Defensive patterns

Strategy: validation

Validate before calling

if (typeof req.method === 'string' && req.method.toUpperCase() !== 'POST') {
  throw new Error('webhook requires POST, got ' + req.method);
}

Type guard

func isMethodNotAllowed(resp *http.Response) bool { return resp != nil && resp.StatusCode == http.StatusMethodNotAllowed }

Try / catch

resp, err := http.Post(url, "application/json", body)
if err == nil && resp.StatusCode == 405 {
    return errors.New("webhook endpoint only accepts POST — fix request method")
}

Prevention

When it happens

Trigger: Sending GET/PUT/DELETE/OPTIONS to the WebhookServer's hook path — e.g. opening the URL in a browser (GET), a health-check prober hitting it with GET, or an API client defaulting to PUT.

Common situations: Verifying the webhook URL by pasting it in a browser; uptime monitors configured for GET; CORS preflight (OPTIONS) reaching the handler; REST clients set to PUT.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/3a4630a41464c476. Report an issue: GitHub.