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

  1. Read the response body in the error message — it contains DingTalk's errcode/errmsg pinpointing the cause
  2. If 401/token errors: verify appKey/appSecret and re-fetch (token may have just expired)
  3. If permission errors: enable the required robot/emotion API permissions for the app in the DingTalk developer console
  4. If 429 or 5xx: back off and retry; check DingTalk status for incidents
  5. 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

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


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