{"record":{"id":"fa96784a6e105431","repo":"chenhg5/cc-connect","slug":"dingtalk-get-access-token-w","errorCode":null,"errorMessage":"dingtalk: get access token: %w","messagePattern":"dingtalk: get access token: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/dingtalk/dingtalk.go","lineNumber":1034,"sourceCode":"\tif !ok {\n\t\treturn fmt.Errorf(\"dingtalk: SendImage: invalid reply context type %T\", rctx)\n\t}\n\n\tname := img.FileName\n\tif name == \"\" {\n\t\tname = \"image.png\"\n\t}\n\n\tmediaID, err := p.uploadMedia(ctx, img.Data, name, \"image\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: upload image: %w\", err)\n\t}\n\n\tslog.Debug(\"dingtalk: image uploaded\", \"media_id\", mediaID, \"size\", len(img.Data))\n\n\ttoken, err := p.getAccessToken()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: get access token: %w\", err)\n\t}\n\n\tmsgParamBytes, _ := json.Marshal(map[string]string{\"photoURL\": mediaID})\n\trequestBody := map[string]any{\n\t\t\"robotCode\": p.robotCode,\n\t\t\"userIds\":   []string{rc.senderStaffId},\n\t\t\"msgKey\":    \"sampleImageMsg\",\n\t\t\"msgParam\":  string(msgParamBytes),\n\t}\n\n\tbody, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: marshal image message: %w\", err)\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost,\n\t\t\"https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend\",\n\t\tbytes.NewReader(body))","sourceCodeStart":1016,"sourceCodeEnd":1052,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/dingtalk.go#L1016-L1052","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify appKey and appSecret are correct and current in the DingTalk developer console","Test reachability of the token endpoint from the host (curl the token URL)","Retry the send — a transient token-fetch failure will likely succeed on retry","If it recurs, check whether the host's clock is skewed (token expiry math depends on it) and confirm the app is not throttled"],"exampleFix":"// before (config)\n[platforms.dingtalk]\nappKey = \"stale-key\"\nappSecret = \"old-secret\"\n// after: rotate to current credentials from the DingTalk console\n[platforms.dingtalk]\nappKey = \"ding0123456789abcdef\"\nappSecret = \"current-secret\"","handlingStrategy":"retry","validationCode":"// Go: pre-flight token check before the image send sequence\nif _, err := p.getAccessToken(); err != nil {\n    return fmt.Errorf(\"dingtalk: token unavailable before SendImage: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := p.SendImage(ctx, rctx, img); err != nil {\n    if strings.Contains(err.Error(), \"get access token\") {\n        time.Sleep(time.Second)\n        err = p.SendImage(ctx, rctx, img) // one retry for transient token failure\n    }\n    if err != nil {\n        slog.Error(\"dingtalk sendImage failed\", \"err\", err)\n    }\n}","preventionTips":["Keep appKey/appSecret current and test with a doctor check at startup","Retry once on token errors — refresh races and expiry edges are common","Verify host clock sync (NTP) so token expiry windows are computed correctly","Monitor DingTalk token-service availability"],"tags":["dingtalk","authentication","access-token","network"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}