chenhg5/cc-connect · error

errcode=%d errmsg=%s

Error message

errcode=%d errmsg=%s

What it means

sendPayload posts to /robot/message/custom/send and checks the API's application-level status. Tuitui returns HTTP 200 with errcode/errmsg in the body; a non-zero errcode means the API rejected the message (auth, permission, bad recipient, rate limit). The adapter surfaces both fields verbatim.

Source

Thrown at platform/tuitui/tuitui.go:692

		}
	} else if isImage {
		payload["msgtype"] = "image"
		payload["image"] = map[string]string{"media_id": mediaID}
	} else {
		payload["msgtype"] = "attachment"
		payload["attachment"] = map[string]string{"media_id": mediaID}
	}
	addTargets(payload, rctx.chatID, rctx.chatType)
	return p.sendPayload(ctx, payload)
}

func (p *Platform) sendPayload(ctx context.Context, payload map[string]any) error {
	var response sendMessageResponse
	if err := p.postJSON(ctx, "/robot/message/custom/send", payload, &response); err != nil {
		return err
	}
	if response.ErrCode != 0 {
		return fmt.Errorf("errcode=%d errmsg=%s", response.ErrCode, response.ErrMsg)
	}
	p.rememberOutboundEcho(response.messageIDs())
	return nil
}

func (p *Platform) postJSON(ctx context.Context, apiPath string, payload any, out any) error {
	data, err := json.Marshal(payload)
	if err != nil {
		return err
	}
	u, err := url.Parse(p.apiBase + apiPath)
	if err != nil {
		return err
	}
	q := u.Query()
	q.Set("appid", p.appID)
	q.Set("secret", p.appSecret)
	u.RawQuery = q.Encode()

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read errmsg in the error: fix the specific API complaint (credentials, recipient ID, content).
  2. Verify the webhook URL and app secret in config.toml are current.
  3. Confirm the bot is still a member of the target chat and has send permission.
  4. If errcode indicates rate limiting, add backoff/retry before resending.

Example fix

// before
err := p.sendPayload(ctx, payload) // errcode=300005, msg ignored
// after
if err != nil {
    slog.Error("tuitui: send failed", "err", err) // shows errcode + errmsg
    if isRateLimitErrcode(err) { time.Sleep(backoff) }
}
Defensive patterns

Strategy: retry

Validate before calling

if rctx.chatID == "" {
    return errors.New("cannot send: empty chatID")
}

Try / catch

if err := p.sendPayload(ctx, payload); err != nil {
    var apiErr errcodeError
    if errors.As(err, &apiErr) && apiErr.Retryable() {
        time.Sleep(backoff); return p.sendPayload(ctx, payload)
    }
    return fmt.Errorf("tuitui send: %w", err)
}

Prevention

When it happens

Trigger: Sending a text/media message where the Tuitui backend answers errcode != 0 — e.g. invalid webhook key, bot not in the chat, message blocked, or rate limited.

Common situations: Rotated or wrong app secret/webhook URL; bot removed from group; message content violating platform rules; exceeding send rate limits.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/7164f3d46e15f373. Report an issue: GitHub.