{"record":{"id":"684384962d2d8e82","repo":"chenhg5/cc-connect","slug":"telegram-invalid-preview-handle-type-t","errorCode":null,"errorMessage":"telegram: invalid preview handle type %T","messagePattern":"telegram: invalid preview handle type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/telegram/telegram.go","lineNumber":1332,"sourceCode":"\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)\n\t}\n\treturn err\n}\n\nfunc (p *Platform) downloadFile(fileID string) ([]byte, error) {\n\tbot, err := p.connectedBot(\"download file\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tctx := context.Background()","sourceCodeStart":1314,"sourceCodeEnd":1350,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/telegram/telegram.go#L1314-L1350","documentation":"DeletePreviewMessage requires the previewHandle argument to be a *telegramPreviewHandle; this error is returned when it is not. Like the reply-context check, it is a contract violation caught at runtime via a type assertion, with %T exposing the offending type.","triggerScenarios":"Calling p.DeletePreviewMessage(ctx, handle) with a handle produced by a different platform adapter, a plain struct copy instead of a pointer, or nil.","commonSituations":"Storing preview handles from multiple platforms in one map keyed by session and passing the wrong one; serializing/deserializing handles so the concrete pointer type is lost; passing the string message ID directly instead of the handle object.","solutions":["Pass the *telegramPreviewHandle exactly as returned by the platform's preview-message send API.","Fix the code path that produced the wrong handle type — check the %T output against platform/telegram's handle type.","Keep platform-specific handles scoped to their platform's code paths.","If handles cross a serialization boundary, store the chatID/messageID fields and rebuild the handle on this side."],"exampleFix":"// before\nplatform.DeletePreviewMessage(ctx, genericHandle)\n// after\nh, ok := genericHandle.(*telegram.PreviewHandle)\nif !ok { return fmt.Errorf(\"unexpected handle %T\", genericHandle) }\nplatform.DeletePreviewMessage(ctx, h)","handlingStrategy":"type-guard","validationCode":"if handle == nil { return errors.New(\"nil preview handle\") }","typeGuard":"func asTelegramPreviewHandle(v any) (*telegramPreviewHandle, bool) {\n    h, ok := v.(*telegramPreviewHandle)\n    return h, ok\n}","tryCatchPattern":"h, ok := previewHandle.(*telegramPreviewHandle)\nif !ok {\n    return fmt.Errorf(\"telegram: invalid preview handle type %T\", previewHandle)\n}","preventionTips":["Store preview handles per-platform, never in a shared cross-platform map","Keep handles as opaque values and only pass them back to the creating platform","Avoid serializing handles across process boundaries","Log %T when handles come from dynamic sources"],"tags":["telegram","type-assertion","preview-message","programmer-error"],"backgroundTag":"type-mismatch","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"}