chenhg5/cc-connect · error
empty media_id in upload response: %s
Error message
empty media_id in upload response: %s
What it means
The media upload API answered HTTP 200 with errcode 0 (success), yet the media_id field in the JSON response is empty. Since a valid media_id is required to send the media later, the platform treats this as a failed upload and returns the raw response body for inspection. This guards against silently succeeding with an unusable media id.
Source
Thrown at platform/dingtalk/dingtalk.go:1402
slog.Debug("dingtalk: media upload response", "status", resp.StatusCode, "body", string(respBody))
var uploadResp struct {
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
MediaID string `json:"media_id"`
Type string `json:"type"`
}
if err := json.Unmarshal(respBody, &uploadResp); err != nil {
return "", fmt.Errorf("decode upload response: %w, body: %s", err, respBody)
}
if uploadResp.ErrCode != 0 {
return "", fmt.Errorf("upload API error %d: %s", uploadResp.ErrCode, uploadResp.ErrMsg)
}
if uploadResp.MediaID == "" {
return "", fmt.Errorf("empty media_id in upload response: %s", respBody)
}
slog.Debug("dingtalk: media uploaded successfully", "media_id", uploadResp.MediaID, "type", mediaType, "size", len(data))
return uploadResp.MediaID, nil
}
func (p *Platform) Stop() error {
if p.streamCtxCancel != nil {
p.streamCtxCancel()
}
if p.streamClient != nil {
p.streamClient.Close()
}
return nil
}
// formatReplyContent prepends quoted text to the message content when the user
// replies to / quotes a previous message. richText is parsed from the raw JSONView on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the body in the error message — check what keys the response actually contains (media_id vs mediaId, nested payload, etc.).
- Confirm you are calling the current official media/upload endpoint for your app type (enterprise internal app vs. custom robot).
- Check the DingTalk Open Platform changelog for response schema changes for media upload.
- Retest with a small, well-formed image upload to rule out type-specific quirks.
- If using a mock/proxy for testing, ensure it returns a non-empty media_id field.
Example fix
// caller-side guard
mediaID, err := platform.UploadMedia(ctx, data, "image")
if err != nil {
if strings.Contains(err.Error(), "empty media_id") {
slog.Warn("dingtalk upload returned success but no media_id; check API version/response keys")
}
return err
} Defensive patterns
Strategy: validation
Validate before calling
// caller-side sanity check after a successful upload
mediaID, err := uploadMedia(ctx, data, mediaType)
if err == nil && mediaID == "" {
return fmt.Errorf("upload returned empty media_id")
} Try / catch
mediaID, err := uploadMedia(ctx, data, mediaType)
if err != nil {
if strings.Contains(err.Error(), "empty media_id") {
// treat as failure; log raw response for API-version debugging
slog.Error("dingtalk upload succeeded without media_id; check API version", "detail", err.Error())
}
return err
} Prevention
- Pin to documented DingTalk API endpoints and review changelogs for response schema changes.
- Always assert non-empty media_id before using it to send media.
- Beware of proxies/mocks that strip or rename response fields.
- Test uploads with a minimal image to catch schema regressions early.
When it happens
Trigger: DingTalk returns a success envelope whose media_id key is absent, null, or an empty string — e.g. a changed/renamed response field in some API version, a success response for a type the account cannot actually store, or a partially-finished upload acknowledged early.
Common situations: DingTalk API behavior change or regional endpoint difference; responses proxied/rewritten by middleware stripping fields; uploading with an app type that acknowledges but does not persist the media; testing against a mocked/stubbed DingTalk API.
Related errors
- upload returned status %d: %s
- decode upload response: %w, body: %s
- upload API error %d: %s
- get access token: %w
- create AI card: status=%d, body=%s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/a8558924dc30071e.
Report an issue: GitHub.