chenhg5/cc-connect · error

dingtalk: get access token: %w

Error message

dingtalk: get access token: %w

What it means

This error is returned by Platform.SendImage when p.getAccessToken() fails after the image was successfully uploaded. The oToMessages batchSend API requires a fresh access token; this error wraps whatever went wrong during the token exchange — network failure to the token endpoint, invalid appKey/appSecret, or an unparseable/rejected token response. The image upload succeeded but the message cannot be sent without a token, so the send aborts.

Source

Thrown at platform/dingtalk/dingtalk.go:1034

	if !ok {
		return fmt.Errorf("dingtalk: SendImage: invalid reply context type %T", rctx)
	}

	name := img.FileName
	if name == "" {
		name = "image.png"
	}

	mediaID, err := p.uploadMedia(ctx, img.Data, name, "image")
	if err != nil {
		return fmt.Errorf("dingtalk: upload image: %w", err)
	}

	slog.Debug("dingtalk: image uploaded", "media_id", mediaID, "size", len(img.Data))

	token, err := p.getAccessToken()
	if err != nil {
		return fmt.Errorf("dingtalk: get access token: %w", err)
	}

	msgParamBytes, _ := json.Marshal(map[string]string{"photoURL": mediaID})
	requestBody := map[string]any{
		"robotCode": p.robotCode,
		"userIds":   []string{rc.senderStaffId},
		"msgKey":    "sampleImageMsg",
		"msgParam":  string(msgParamBytes),
	}

	body, err := json.Marshal(requestBody)
	if err != nil {
		return fmt.Errorf("dingtalk: marshal image message: %w", err)
	}

	req, err := http.NewRequestWithContext(ctx, http.MethodPost,
		"https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend",
		bytes.NewReader(body))

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Verify appKey and appSecret are correct and current in the DingTalk developer console
  2. Test reachability of the token endpoint from the host (curl the token URL)
  3. Retry the send — a transient token-fetch failure will likely succeed on retry
  4. If it recurs, check whether the host's clock is skewed (token expiry math depends on it) and confirm the app is not throttled

Example fix

// before (config)
[platforms.dingtalk]
appKey = "stale-key"
appSecret = "old-secret"
// after: rotate to current credentials from the DingTalk console
[platforms.dingtalk]
appKey = "ding0123456789abcdef"
appSecret = "current-secret"
Defensive patterns

Strategy: retry

Validate before calling

// Go: pre-flight token check before the image send sequence
if _, err := p.getAccessToken(); err != nil {
    return fmt.Errorf("dingtalk: token unavailable before SendImage: %w", err)
}

Try / catch

if err := p.SendImage(ctx, rctx, img); err != nil {
    if strings.Contains(err.Error(), "get access token") {
        time.Sleep(time.Second)
        err = p.SendImage(ctx, rctx, img) // one retry for transient token failure
    }
    if err != nil {
        slog.Error("dingtalk sendImage failed", "err", err)
    }
}

Prevention

When it happens

Trigger: getAccessToken() returns an error inside SendImage after uploadMedia succeeded — token endpoint unreachable, expired cached token and failed refresh, empty/incorrect appKey/appSecret, or token API returning an error payload.

Common situations: appKey/appSecret misconfigured or rotated in the DingTalk console; token just expired with refresh hitting a network glitch; firewall intermittently blocking DingTalk endpoints; DingTalk token service outage.

Related errors


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