chenhg5/cc-connect · error
HTTP %d: %s
Error message
HTTP %d: %s
What it means
postJSON treats any HTTP status outside 200-299 as a failure and includes up to the whole response body in the error. This means the transport succeeded but the Tuitui API (or an intermediary) returned an error status such as 401, 403, 404 or 500.
Source
Thrown at platform/tuitui/tuitui.go:729
req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), bytes.NewReader(data))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
resp, err := p.client.Do(req)
if err != nil {
return errorsRedacted(err, p.appSecret)
}
defer func() { _ = resp.Body.Close() }()
body, err := io.ReadAll(io.LimitReader(resp.Body, maxJSONResponseBytes+1))
if err != nil {
return err
}
if len(body) > maxJSONResponseBytes {
return fmt.Errorf("tuitui: %s response exceeds %d bytes", apiPath, maxJSONResponseBytes)
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("HTTP %d: %s", resp.StatusCode, body)
}
var apiResp struct {
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
}
if out != nil {
if err := json.Unmarshal(body, out); err != nil {
return fmt.Errorf("tuitui: decode %s response: %w (body_len=%d)", apiPath, err, len(body))
}
return nil
}
if len(bytes.TrimSpace(body)) == 0 {
return nil
}
if err := json.Unmarshal(body, &apiResp); err != nil {
return fmt.Errorf("tuitui: decode %s response: %w (body_len=%d)", apiPath, err, len(body))
}
if apiResp.ErrCode != 0 {View on GitHub (pinned to 4000b2338a)
Solutions
- Check the HTTP status and body in the error: 401/403 means re-check appSecret/webhook credentials in config.toml.
- 404: verify the API path/base URL matches the current Tuitui API version.
- 5xx: retry with backoff; check Tuitui service status.
- Confirm network/proxy settings aren't intercepting or rewriting requests.
Example fix
// before
// HTTP 401: {"errmsg":"invalid app_secret"} — stale secret in config
// after
# config.toml
[platforms.tuitui]
app_secret = "<newly-rotated-secret>" Defensive patterns
Strategy: retry
Validate before calling
if p.appSecret == "" || p.webhookBase == "" {
return errors.New("tuitui credentials/base URL not configured")
} Try / catch
if err := p.postJSON(ctx, path, req, &out); err != nil {
var httpErr httpStatusError
if errors.As(err, &httpErr) && httpErr.StatusCode >= 500 {
return retryWithBackoff(ctx, call)
}
return err // 4xx: fix credentials/URL, don't retry
} Prevention
- Rotate app secrets in config immediately after upstream rotation
- Validate the base URL against current API docs
- Distinguish 4xx (fix config) from 5xx (retry) before acting
When it happens
Trigger: Expired/invalid app secret (401/403), wrong API path (404), server error (5xx) on any postJSON call: history fetches, getChannelInfo, reactToMessage, sendPayload.
Common situations: Rotated Tuitui credentials not updated in config; typo in webhook base URL; Tuitui outage or gateway error page; corporate proxy intercepting requests.
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
- errcode=%d errmsg=%s
- usage endpoint returned status %d: %s
- reasonix: POST %s returned %d: %s
- gitee API returned HTTP %d
- http %d: %s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/337d70cd379cb992.
Report an issue: GitHub.