{"record":{"id":"de843d54f114490b","repo":"chenhg5/cc-connect","slug":"weixin-sendtext-empty-item-list","errorCode":null,"errorMessage":"weixin: sendText: empty item_list","messagePattern":"weixin: sendText: empty item_list","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/weixin/client.go","lineNumber":265,"sourceCode":"\t\treturn err\n\t}\n\t_, err = c.post(ctx, \"ilink/bot/sendtyping\", payload, 0, \"sendTyping\")\n\treturn err\n}\n\nfunc (c *apiClient) sendText(ctx context.Context, to, text, contextToken, clientID string) error {\n\tif strings.TrimSpace(contextToken) == \"\" {\n\t\treturn fmt.Errorf(\"weixin: context_token is required for send\")\n\t}\n\titems := []messageItem{}\n\tif strings.TrimSpace(text) != \"\" {\n\t\titems = append(items, messageItem{\n\t\t\tType:     messageItemText,\n\t\t\tTextItem: &textItem{Text: text},\n\t\t})\n\t}\n\tif len(items) == 0 {\n\t\treturn fmt.Errorf(\"weixin: sendText: empty item_list\")\n\t}\n\tmsg := sendMessageReq{\n\t\tMsg: weixinOutboundMsg{\n\t\t\tFromUserID:   \"\",\n\t\t\tToUserID:     to,\n\t\t\tClientID:     clientID,\n\t\t\tMessageType:  messageTypeBot,\n\t\t\tMessageState: messageStateFinish,\n\t\t\tItemList:     items,\n\t\t\tContextToken: contextToken,\n\t\t},\n\t}\n\treturn c.sendMessage(ctx, &msg)\n}\n","sourceCodeStart":247,"sourceCodeEnd":280,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/weixin/client.go#L247-L280","documentation":"sendText assembles an item_list for the sendMessage API; normally a non-empty text always yields one item. If items is still empty (e.g. text is blank and no other items were added), the request would be invalid, so the client returns this error instead of posting a pointless API call.","triggerScenarios":"sendText called with whitespace-only or empty text and no additional items — e.g. sendChunks/sendChunk flushing a final empty chunk, or an upstream empty-message edge case.","commonSituations":"Streaming implementations sending a trailing empty chunk; splitting logic producing zero-length final pieces; callers using sendText as a heartbeat/no-op.","solutions":["Guard at the call site: skip sendText when strings.TrimSpace(text) == \"\"","Fix the chunker so empty trailing chunks are not dispatched","If a no-op is intended, return nil without calling the API"],"exampleFix":"// before\nif err := c.sendText(ctx, to, chunk, token, id); err != nil { ... }\n// after\nif strings.TrimSpace(chunk) != \"\" {\n\tif err := c.sendText(ctx, to, chunk, token, id); err != nil { ... }\n}","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(text) == \"\" { return nil } // nothing to send","typeGuard":"func hasSendableText(t string) bool { return strings.TrimSpace(t) != \"\" }","tryCatchPattern":"if err := sendText(ctx, to, text, token, id); err != nil {\n\tif strings.Contains(err.Error(), \"empty item_list\") { slog.Debug(\"skipped empty send\") ; return nil }\n\treturn err\n}","preventionTips":["Filter empty/whitespace chunks before calling sendText","Fix chunk splitting to never emit zero-length pieces","Treat this error as a no-op signal rather than a hard failure in streaming flows"],"tags":["weixin","validation","empty","send"],"backgroundTag":"empty-required-field","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"}