chenhg5/cc-connect · warning
POST only
Error message
POST only
What it means
The cc-connect local HTTP API's /send endpoint only accepts POST requests; any other method (GET, PUT, DELETE) is rejected with 405 and the body "POST only". Sending a message requires a request body, so GET-style access is not supported by design.
Source
Thrown at core/api.go:205
slog.Debug("api server close failed", "error", err)
}
}
if err := os.Remove(s.socketPath); err != nil && !os.IsNotExist(err) {
slog.Debug("api server remove socket failed", "error", err)
}
}
func apiJSON(w http.ResponseWriter, status int, v any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(v); err != nil {
slog.Error("api server: write JSON failed", "error", err)
}
}
func (s *APIServer) handleSend(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "POST only", http.StatusMethodNotAllowed)
return
}
// Attachments travel base64-encoded inside the JSON body (~4/3 expansion)
// plus the request envelope, so size the reader to fit one max-size
// attachment with overhead to spare. The previous hard-coded 52 MB cap was
// smaller than a single 50 MB attachment after base64 encoding and would
// reject valid sends; deriving it from maxAttachmentBytes keeps the body
// limit in step with the configured attachment limit.
var req SendRequest
if err := json.NewDecoder(io.LimitReader(r.Body, s.sendBodyLimit())).Decode(&req); err != nil {
http.Error(w, "invalid JSON: "+err.Error(), http.StatusBadRequest)
return
}
if req.Message == "" && strings.TrimSpace(req.TTSText) == "" && len(req.Images) == 0 && len(req.Files) == 0 && len(req.Audios) == 0 && len(req.Videos) == 0 {
http.Error(w, "message, tts_text, or attachment is required", http.StatusBadRequest)
return
}View on GitHub (pinned to 4000b2338a)
Solutions
- Send the request with POST: `curl -X POST http://127.0.0.1:<port>/send -d '{...}'`.
- In client code use http.NewRequest("POST", url, body) instead of http.Get.
- If a monitoring probe hit the route, point the probe at a GET-safe health endpoint instead.
- Check for redirects: a 301/302 from http to https can downgrade POST to GET — use the correct scheme directly.
Example fix
// before
resp, err := http.Get("http://127.0.0.1:8080/send")
// after
resp, err := http.Post("http://127.0.0.1:8080/send", "application/json",
strings.NewReader(`{"message":"hi"}`)) Defensive patterns
Strategy: validation
Validate before calling
if req.Method != http.MethodPost {
panic("/send requires POST")
} Try / catch
resp, err := client.Do(req)
if resp.StatusCode == http.StatusMethodNotAllowed {
// fix client to use POST and retry once
} Prevention
- Use POST for every /send call; never http.Get
- Point GET-based health probes at a health endpoint, not /send
- Beware redirects downgrading POST to GET — call the final URL directly
When it happens
Trigger: Calling the API server's send route with r.Method != http.MethodPost — e.g. opening the URL in a browser (GET) or using a client that defaults to GET.
Common situations: Testing the endpoint in a browser address bar, curl without -X POST and without -d, a script using http.Get on the send path, health-check probes configured with GET against the send route.
Related errors
- usage endpoint returned status %d: %s
- reasonix: POST %s returned %d: %s
- gitee API returned HTTP %d
- http %d: %s
- whisper API %d: %s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/cd1b99004ac31da1.
Report an issue: GitHub.