{"record":{"id":"6d31d4e2f3d6e5fe","repo":"chenhg5/cc-connect","slug":"reasonix-post-s-w","errorCode":null,"errorMessage":"reasonix: POST %s: %w","messagePattern":"reasonix: POST (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/reasonix/session.go","lineNumber":492,"sourceCode":"func (s *reasonixSession) httpPost(path string, body any) error {\n\tvar reqBody io.Reader\n\tif body != nil {\n\t\tdata, err := json.Marshal(body)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"reasonix: marshal body: %w\", err)\n\t\t}\n\t\treqBody = bytes.NewReader(data)\n\t}\n\n\treq, err := http.NewRequestWithContext(s.ctx, \"POST\", s.serveURL+path, reqBody)\n\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","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/reasonix/session.go#L474-L510","documentation":"httpPost performs the request with http.DefaultClient.Do and wraps any transport-level failure as 'reasonix: POST %s: %w'. This covers DNS failure, connection refused, TLS errors, timeouts, and — importantly — context cancellation of the session (e.g. session closed while a request was in flight).","triggerScenarios":"During newSession, Send, or RespondPermission the POST to the reasonix serve endpoint fails at the transport layer: serve process not running, wrong host/port, network partition, TLS handshake failure, or s.ctx already canceled.","commonSituations":"Reasonix serve not started before cc-connect; serve_url pointing at the wrong port; firewall blocking localhost; long Send hitting an idle timeout; session Stop() racing an in-flight RespondPermission.","solutions":["Confirm the reasonix serve process is running and listening (curl the serveURL health endpoint)","Check the wrapped error: 'connection refused' means wrong port/dead process; 'context canceled' means the session was closed mid-request","Correct serve_url in config.toml (host/port) and restart","If context-canceled races are frequent, guard Send/RespondPermission with an alive check before issuing requests"],"exampleFix":"// before: request races session shutdown\nerr := s.httpPost(\"/message\", body)\n// after: bail early on closed session\nif s.ctx.Err() != nil {\n    return fmt.Errorf(\"reasonix: session closed\")\n}\nerr := s.httpPost(\"/message\", body)","handlingStrategy":"retry","validationCode":"// probe before use\nresp, err := http.Get(serveURL + \"/health\")\nif err != nil { return fmt.Errorf(\"reasonix serve unreachable: %w\", err) }","typeGuard":null,"tryCatchPattern":"// Go: distinguish cancel vs transport failure\nif err := sess.Send(...); err != nil {\n    if errors.Is(err, context.Canceled) {\n        return // session closed; don't retry\n    }\n    // transient network failure: retry with backoff\n    retry.WithBackoff(3, func() error { return sess.Send(...) })\n}","preventionTips":["Start the reasonix serve process before cc-connect and supervise it (systemd)","Health-check the endpoint at startup and on a timer","Match host/port between serve and config; avoid timeout-prone proxies on localhost"],"tags":["network","http","connection"],"backgroundTag":"connection-refused","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"}