chenhg5/cc-connect · error
dingtalk: emotion returned status %d: %s
Error message
dingtalk: emotion returned status %d: %s
What it means
This error is returned by sendEmotion when DingTalk's emotion API responds with a non-200 HTTP status code. The message includes the status code and the raw response body, which contains DingTalk's machine-readable error code and message (e.g. invalid authentication, forbidden robot, throttled request). It means the request reached DingTalk and was rejected at the HTTP layer — unlike err 1063, this is an application-level refusal, not a transport failure.
Source
Thrown at platform/dingtalk/dingtalk.go:967
return fmt.Errorf("dingtalk: marshal emotion request: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://api.dingtalk.com"+path, bytes.NewReader(body))
if err != nil {
return fmt.Errorf("dingtalk: create emotion request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-acs-dingtalk-access-token", token)
resp, err := p.httpClient.Do(req)
if err != nil {
return fmt.Errorf("dingtalk: emotion request: %w", err)
}
defer func() { _ = resp.Body.Close() }()
respBody, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("dingtalk: emotion returned status %d: %s", resp.StatusCode, string(respBody))
}
if len(respBody) == 0 {
return nil
}
var result struct {
Success *bool `json:"success"`
}
if err := json.Unmarshal(respBody, &result); err == nil && result.Success != nil && !*result.Success {
return fmt.Errorf("dingtalk: emotion returned success=false")
}
return nil
}
// StartTyping adds a DingTalk emotion to the user's message while the agent is processing.
func (p *Platform) StartTyping(ctx context.Context, rctx any) (stop func()) {
rc, ok := rctx.(replyContext)
if !ok || p.reactionEmoji == "" || rc.messageID == "" || rc.conversationId == "" {
return func() {}View on GitHub (pinned to 4000b2338a)
Solutions
- Read the response body in the error message — it contains DingTalk's errcode/errmsg pinpointing the cause
- If 401/token errors: verify appKey/appSecret and re-fetch (token may have just expired)
- If permission errors: enable the required robot/emotion API permissions for the app in the DingTalk developer console
- If 429 or 5xx: back off and retry; check DingTalk status for incidents
- Confirm the emoji/backgroundID payload matches DingTalk's documented values
Example fix
// before: reacting with an app lacking emotion permission -> status 403 // after: enable "企业机器人-表情回复" (robot emotion) API permission // in DingTalk open platform console under the app's Permission Management, then redeploy
Defensive patterns
Strategy: try-catch
Validate before calling
// Go: pre-flight token check to avoid 401-class rejections
tok, err := p.getAccessToken()
if err != nil || tok == "" {
return fmt.Errorf("dingtalk: no valid token before emotion send: %w", err)
} Try / catch
if err := p.AddDoneReaction(ctx, msg); err != nil {
var httpErr interface{ Error() string }
if strings.Contains(err.Error(), "emotion returned status") {
// parse embedded status/body for DingTalk errcode
slog.Warn("dingtalk emotion rejected", "detail", err)
}
_ = httpErr
} Prevention
- Grant the robot app all emotion-reply API scopes in the DingTalk console before enabling features
- Handle 401/403 by refreshing credentials rather than blind retries
- Log the response body embedded in the error — it carries DingTalk's errcode/errmsg
- Watch DingTalk status pages for 5xx incidents
When it happens
Trigger: p.httpClient.Do succeeds but resp.StatusCode != 200 for /v1.0/robot/emotion/reply or /robot/emotion/recall — expired/invalid access token (401/400), robot not permitted for emotion replies, invalid backgroundID/emoji payload, or DingTalk server errors (5xx).
Common situations: Access token expired between fetch and use; app lacks the Robot emotion API permission scope in the DingTalk console; calling reply on a message the robot is not allowed to react to; DingTalk-side 5xx during an incident.
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
- create AI card: status=%d, body=%s
- stream AI card: status=%d, body=%s
- create request: %w
- do request: %w
- api returned status %d
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/ae1d4ed8a27797ba.
Report an issue: GitHub.