{"record":{"id":"0d92599fe5390724","repo":"chenhg5/cc-connect","slug":"reasonix-post-s-returned-d-s","errorCode":null,"errorMessage":"reasonix: POST %s returned %d: %s","messagePattern":"reasonix: POST (.+?) returned (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/reasonix/session.go","lineNumber":503,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"reasonix: create request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"reasonix: POST %s: %w\", path, err)\n\t}\n\tdefer func() {\n\t\tif err := resp.Body.Close(); err != nil {\n\t\t\tslog.Warn(\"reasonix: POST close body\", \"path\", path, \"error\", err)\n\t\t}\n\t}()\n\n\tif resp.StatusCode >= 400 {\n\t\t// Include response body (first 512 bytes) in error for debugging.\n\t\terrBody, _ := io.ReadAll(io.LimitReader(resp.Body, 512))\n\t\treturn fmt.Errorf(\"reasonix: POST %s returned %d: %s\", path, resp.StatusCode, strings.TrimSpace(string(errBody)))\n\t}\n\treturn nil\n}\n\n// formatImages builds a comma-separated list of image filenames for inclusion\n// in the prompt. Reasons adopts the standard cc-connect file-save pattern so\n// the actual image bytes land on disk (via core.SaveFilesToDisk); this list\n// gives reasonix serve a human-readable hint about which images were attached.\nfunc formatImages(images []core.ImageAttachment) string {\n\tnames := make([]string, len(images))\n\tfor i, img := range images {\n\t\tif img.FileName != \"\" {\n\t\t\tnames[i] = img.FileName\n\t\t} else {\n\t\t\tnames[i] = fmt.Sprintf(\"image_%d\", i)\n\t\t}\n\t}\n\treturn strings.Join(names, \", \")","sourceCodeStart":485,"sourceCodeEnd":521,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/reasonix/session.go#L485-L521","documentation":"When the reasonix serve endpoint responds with HTTP status >= 400, httpPost reads up to 512 bytes of the response body and returns 'reasonix: POST %s returned %d: %s' including that body for debugging. This turns server-side rejections (bad request, auth, not found, 5xx) into actionable error messages.","triggerScenarios":"The serve endpoint replies 400/401/404/500 etc. to a POST issued from newSession, Send, or RespondPermission — e.g. unknown path, invalid session id, malformed payload the server rejects, or the server itself erroring.","commonSituations":"Version mismatch between cc-connect and the reasonix serve API (endpoint renamed → 404); expired/missing auth token → 401; prompt payload exceeding a server limit → 400/413; serve process crash-looping → 502/503 from a proxy.","solutions":["Read the response-body snippet embedded in the error — it states the server's own reason","Check status: 404 → API path/version mismatch, update reasonix serve or cc-connect; 401/403 → fix credentials; 5xx → inspect serve logs","Verify the request payload matches the serve endpoint's expected schema for that path","If a proxy sits in front of serve, check proxy error logs for the upstream failure"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Go\nif err := sess.Send(...); err != nil {\n    var herr string\n    if n, _ := fmt.Sscanf(err.Error(), \"reasonix: POST %s returned\", &herr); n == 1 || strings.Contains(err.Error(), \"returned \") {\n        slog.Error(\"reasonix server rejected request\", \"detail\", err)\n    }\n}","preventionTips":["Pin compatible versions of cc-connect adapter and reasonix serve","Keep request payloads within the endpoint's documented limits","Monitor 5xx rates on the serve endpoint","Include response bodies in logs (as this error does) for fast diagnosis"],"tags":["http","api","server-error"],"backgroundTag":"http-error-response","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}