{"record":{"id":"306eab2da961a57e","repo":"chenhg5/cc-connect","slug":"cloud-web-send-http-d-s-306eab","errorCode":null,"errorMessage":"cloud_web: send HTTP %d: %s","messagePattern":"cloud_web: send HTTP (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/cloud-web/poll.go","lineNumber":254,"sourceCode":"\tbody, err := json.Marshal(msg)\n\tif err != nil {\n\t\treturn err\n\t}\n\turl := joinURL(t.baseURL, t.sendPath)\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tauthHTTP(req, t.token)\n\tresp, err := t.client.Do(req)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\traw, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20))\n\tif resp.StatusCode >= 300 {\n\t\treturn fmt.Errorf(\"cloud_web: send HTTP %d: %s\", resp.StatusCode, string(raw))\n\t}\n\t// Handle inline preview_ack in send response.\n\tvar ack wirePreviewAck\n\tif json.Unmarshal(raw, &ack) == nil && ack.Type == \"preview_ack\" && ack.RefID != \"\" {\n\t\tt.previewMu.Lock()\n\t\tch, ok := t.previewRequests[ack.RefID]\n\t\tif ok {\n\t\t\tdelete(t.previewRequests, ack.RefID)\n\t\t}\n\t\tt.previewMu.Unlock()\n\t\tif ok {\n\t\t\tch <- ack.PreviewHandle\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (t *pollTransport) waitPreviewAck(refID string, timeout time.Duration) (string, error) {","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/cloud-web/poll.go#L236-L272","documentation":"The long-poll transport POSTed an outbound message to the cloud-web send endpoint and received HTTP status >= 300, so the message was not accepted. The error carries the status code and the beginning of the response body. The transport does not retry; the caller (engine) gets this error back.","triggerScenarios":"Send() gets a 3xx/4xx/5xx from POST {base_url}/{send_path}: 401 token mismatch, 404 wrong base_url/send_path, 429 rate limiting, 500/502 server or proxy failure.","commonSituations":"Shared secret rotated without updating cc-connect; base_url pointing at a host that fronts the send API differently; server rate-limiting a chatty bot (429); upstream outage causing 502/503 through a proxy.","solutions":["Read status from the error: 401 -> fix token; 404 -> fix base_url/send_path; 429 -> back off and reduce send rate; 5xx -> check server.","Confirm the token in config.toml matches the server secret.","curl the send endpoint with the same payload and Authorization header to reproduce.","For transient 5xx/429, resend the message after a delay once the server recovers."],"exampleFix":"// config.toml — before\nsend_path = \"/v1/send\"   # server serves /api/v1/send -> 404\n\n// after\nsend_path = \"/api/v1/send\"","handlingStrategy":"retry","validationCode":"// pre-validate send path and auth with a ping-style payload\nreq, _ := http.NewRequest(\"POST\", baseURL+sendPath, strings.NewReader(\"{}\"))\nreq.Header.Set(\"Authorization\", \"Bearer \"+token)\nresp, err := http.DefaultClient.Do(req)\nif err == nil {\n    resp.Body.Close()\n    if resp.StatusCode >= 300 {\n        return fmt.Errorf(\"send endpoint returned %d before go-live\", resp.StatusCode)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := platform.Send(ctx, msg); err != nil {\n    if strings.Contains(err.Error(), \"send HTTP 429\") {\n        time.Sleep(backoff)\n        return platform.Send(ctx, msg)\n    }\n    if strings.Contains(err.Error(), \"send HTTP 5\") {\n        slog.Warn(\"server error on send; retrying once\", \"error\", err)\n        return platform.Send(ctx, msg)\n    }\n    return err // 401/404: configuration problem, do not retry\n}","preventionTips":["Classify failures: retry 429/5xx with backoff; fix config for 401/404","Reduce send rate or batch messages if the server rate-limits (429)","Verify base_url and send_path after every server route change","Include the send endpoint in deployment smoke tests"],"tags":["http","api-error","send","cloud-web"],"backgroundTag":"api-error-response","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}