chenhg5/cc-connect · error

reasonix: POST %s returned %d: %s

Error message

reasonix: POST %s returned %d: %s

What it means

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.

Source

Thrown at agent/reasonix/session.go:503

	if err != nil {
		return fmt.Errorf("reasonix: create request: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return fmt.Errorf("reasonix: POST %s: %w", path, err)
	}
	defer func() {
		if err := resp.Body.Close(); err != nil {
			slog.Warn("reasonix: POST close body", "path", path, "error", err)
		}
	}()

	if resp.StatusCode >= 400 {
		// Include response body (first 512 bytes) in error for debugging.
		errBody, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
		return fmt.Errorf("reasonix: POST %s returned %d: %s", path, resp.StatusCode, strings.TrimSpace(string(errBody)))
	}
	return nil
}

// formatImages builds a comma-separated list of image filenames for inclusion
// in the prompt. Reasons adopts the standard cc-connect file-save pattern so
// the actual image bytes land on disk (via core.SaveFilesToDisk); this list
// gives reasonix serve a human-readable hint about which images were attached.
func formatImages(images []core.ImageAttachment) string {
	names := make([]string, len(images))
	for i, img := range images {
		if img.FileName != "" {
			names[i] = img.FileName
		} else {
			names[i] = fmt.Sprintf("image_%d", i)
		}
	}
	return strings.Join(names, ", ")

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read the response-body snippet embedded in the error — it states the server's own reason
  2. Check status: 404 → API path/version mismatch, update reasonix serve or cc-connect; 401/403 → fix credentials; 5xx → inspect serve logs
  3. Verify the request payload matches the serve endpoint's expected schema for that path
  4. If a proxy sits in front of serve, check proxy error logs for the upstream failure
Defensive patterns

Strategy: try-catch

Try / catch

// Go
if err := sess.Send(...); err != nil {
    var herr string
    if n, _ := fmt.Sscanf(err.Error(), "reasonix: POST %s returned", &herr); n == 1 || strings.Contains(err.Error(), "returned ") {
        slog.Error("reasonix server rejected request", "detail", err)
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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/0d92599fe5390724. Report an issue: GitHub.