chenhg5/cc-connect · error
weixin: getUploadUrl: empty upload_param and upload_full_url
Error message
weixin: getUploadUrl: empty upload_param and upload_full_url in %s
What it means
After decoding getuploadurl's response, the client validates it actually contains an upload address. WeChat's iLink API changed from returning upload_param to upload_full_url; if BOTH are empty, no usable CDN upload target exists and the client refuses to continue with a body snippet for debugging.
Source
Thrown at platform/weixin/client.go:209
func (c *apiClient) getUploadURL(ctx context.Context, req getUploadURLRequest) (*getUploadURLResponse, error) {
req.BaseInfo = baseInfo{ChannelVersion: channelVersion}
payload, err := json.Marshal(req)
if err != nil {
return nil, err
}
raw, err := c.post(ctx, "ilink/bot/getuploadurl", payload, 0, "getUploadUrl")
if err != nil {
return nil, err
}
var out getUploadURLResponse
if err := json.Unmarshal(raw, &out); err != nil {
return nil, fmt.Errorf("weixin: getUploadUrl json: %w", err)
}
// 兼容微信 iLink API 变更:新版返回 upload_full_url 而非 upload_param
// upload_full_url 是完整的 CDN 上传地址,可独立作为成功路径
if strings.TrimSpace(out.UploadParam) == "" && strings.TrimSpace(out.UploadFullURL) == "" {
return nil, fmt.Errorf("weixin: getUploadUrl: empty upload_param and upload_full_url in %s", truncateForLog(raw, 512))
}
return &out, nil
}
func (c *apiClient) getConfig(ctx context.Context, userID, contextToken string) (*getConfigResp, error) {
req := getConfigReq{
UserID: userID,
ContextToken: contextToken,
BaseInfo: baseInfo{ChannelVersion: channelVersion},
}
payload, err := json.Marshal(req)
if err != nil {
return nil, err
}
raw, err := c.post(ctx, "ilink/bot/getconfig", payload, 0, "getConfig")
if err != nil {
return nil, err
}View on GitHub (pinned to 4000b2338a)
Solutions
- Log/inspect the returned body snippet in the error to find the actual field names
- Update getUploadURLResponse to parse the new upload-address field and treat it as valid
- Re-authenticate/refresh the ticket if the API returns empty addresses for stale sessions
- Retry once before surfacing the error, in case of transient degradation
Example fix
// before
if strings.TrimSpace(out.UploadParam) == "" && strings.TrimSpace(out.UploadFullURL) == "" {
return nil, fmt.Errorf("weixin: getUploadUrl: empty upload_param and upload_full_url in %s", ...)
}
// after: accept a newly introduced field too
if strings.TrimSpace(out.UploadParam) == "" && strings.TrimSpace(out.UploadFullURL) == "" && strings.TrimSpace(out.UploadURL) == "" {
return nil, fmt.Errorf("weixin: getUploadUrl: no upload address in %s", truncateForLog(raw, 512))
} Defensive patterns
Strategy: fallback
Validate before calling
if strings.TrimSpace(resp.UploadParam) == "" && strings.TrimSpace(resp.UploadFullURL) == "" { /* treat as failure before calling CDN */ } Type guard
func hasUploadAddress(r *getUploadURLResponse) bool {
return r != nil && (strings.TrimSpace(r.UploadParam) != "" || strings.TrimSpace(r.UploadFullURL) != "")
} Try / catch
addr, err := getUploadURL(ctx, req)
if err != nil || !hasUploadAddress(addr) {
slog.Warn("weixin: no upload address; retrying once", "err", err)
addr, err = getUploadURL(ctx, req)
if err != nil { return err }
} Prevention
- Track WeChat iLink API changelog for new upload-address fields
- Refresh tickets when empty addresses recur
- Retain the raw-body snippet in errors for fast diagnosis
When it happens
Trigger: The API response decodes fine but lacks both UploadParam and UploadFullURL — server-side rejection embedded in a 200 body, degraded API response, or yet another schema change introducing a new field name.
Common situations: WeChat iLink API protocol drift (the exact scenario this guard was added for); expired ticket yielding an empty success body; regional API versions with different field names.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- empty attachment data
- aes key must be 16 bytes, got %d
- %s: CDN upload client error %d: %s
- %s: CDN response missing x-encrypted-param
- %s: CDN upload failed after %d attempts: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/2e62473baedb111a.
Report an issue: GitHub.