{"record":{"id":"a4b66b65d2cdcfbb","repo":"chenhg5/cc-connect","slug":"telegram-sendwithbuttons-w","errorCode":null,"errorMessage":"telegram: sendWithButtons: %w","messagePattern":"telegram: sendWithButtons: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/telegram/telegram.go","lineNumber":1322,"sourceCode":"\t\t\tslog.Warn(\"telegram: HTML rejected by Telegram, sending as plain text\",\n\t\t\t\t\"method\", \"SendWithButtons\",\n\t\t\t\t\"error\", errMsg,\n\t\t\t\t\"html_prefix\", truncateForLog(html, 200),\n\t\t\t\t\"html_len\", len(html),\n\t\t\t)\n\t\t\tparams.Text = content\n\t\t\tparams.ParseMode = \"\"\n\t\t\t_, err = bot.SendMessage(ctx, params)\n\t\t} else if strings.Contains(errMsg, \"message is too long\") {\n\t\t\t// Handle message too long: first chunk with buttons, rest without\n\t\t\tslog.Warn(\"telegram: message too long, splitting into chunks\",\n\t\t\t\t\"method\", \"SendWithButtons\",\n\t\t\t\t\"html_len\", len(html),\n\t\t\t)\n\t\t\treturn p.sendChunkedWithButtons(ctx, bot, rc, html, rows)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"telegram: sendWithButtons: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// DeletePreviewMessage deletes a stale preview message so the caller can send a fresh one.\nfunc (p *Platform) DeletePreviewMessage(ctx context.Context, previewHandle any) error {\n\th, ok := previewHandle.(*telegramPreviewHandle)\n\tif !ok {\n\t\treturn fmt.Errorf(\"telegram: invalid preview handle type %T\", previewHandle)\n\t}\n\tbot, err := p.connectedBot(\"delete preview\")\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = bot.DeleteMessage(ctx, &tgbot.DeleteMessageParams{ChatID: h.chatID, MessageID: h.messageID})\n\tif err != nil {\n\t\tslog.Debug(\"telegram: delete preview message failed\", \"error\", err)","sourceCodeStart":1304,"sourceCodeEnd":1340,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/telegram/telegram.go#L1304-L1340","documentation":"This wraps an error from the actual Telegram Bot API message-send performed inside SendWithButtons, after the HTML body was rendered and chunking was not needed. It indicates the sendMessage call with an inline keyboard failed — the reply context type was valid, but delivery failed.","triggerScenarios":"p.sendWithButtons (or the Bot API call inside it) returns err after the chunking branch: e.g. sendMessage rejects the markup, the text, or the network request fails.","commonSituations":"Inline keyboard rows exceeding Telegram limits (too many buttons/bad callback data >64 bytes); markdown/HTML parse error ('can't parse entities'); message text >4096 chars without chunking; network or 429 rate-limit errors.","solutions":["Read the wrapped error for the Bot API description; fix the specific violation (button callback data ≤64 bytes, valid HTML entities).","Ensure user content is HTML-escaped before rendering so entity parsing cannot fail.","Fall back to sendChunkedWithButtons when len(html) exceeds limits — the code already does this above; verify thresholds.","Retry with backoff on 429/5xx responses."],"exampleFix":"// before\nhtml := fmt.Sprintf(\"<b>%s</b>\", userText)\n// after: escape to avoid 'can't parse entities'\nhtml := \"<b>\" + html.EscapeString(userText) + \"</b>\"","handlingStrategy":"try-catch","validationCode":"if len(content) > 4096 { /* use chunked send */ }\nfor _, row := range buttons { for _, b := range row { if len(b.CallbackData) > 64 { return errors.New(\"callback data too long\") } } }","typeGuard":null,"tryCatchPattern":"if err := p.sendWithButtons(ctx, bot, rc, html, rows); err != nil {\n    if strings.Contains(err.Error(), \"can't parse entities\") { /* escape HTML and retry */ }\n    return fmt.Errorf(\"telegram: sendWithButtons: %w\", err)\n}","preventionTips":["HTML-escape all user content before sending","Keep button callback data ≤64 bytes","Chunk messages longer than 4096 characters","Retry on 429 with the server-provided delay"],"tags":["telegram","bot-api","inline-keyboard","message-send"],"backgroundTag":"api-request-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"}