{"record":{"id":"be4f23903ba4d95d","repo":"chenhg5/cc-connect","slug":"getme-w","errorCode":null,"errorMessage":"getMe: %w","messagePattern":"getMe: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"platform/telegram/telegram.go","lineNumber":271,"sourceCode":"\thandler := func(ctx context.Context, b *tgbot.Bot, update *models.Update) {\n\t\tonUpdate(ctx, update)\n\t}\n\topts := []tgbot.Option{\n\t\ttgbot.WithDefaultHandler(handler),\n\t\ttgbot.WithNotAsyncHandlers(),\n\t}\n\tif httpClient != nil {\n\t\topts = append(opts, tgbot.WithHTTPClient(60*time.Second, httpClient))\n\t}\n\tb, err := tgbot.New(token, opts...)\n\tif err != nil {\n\t\treturn nil, nil, nil, err\n\t}\n\tctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\n\tdefer cancel()\n\tme, err := b.GetMe(ctx)\n\tif err != nil {\n\t\treturn nil, nil, nil, fmt.Errorf(\"getMe: %w\", err)\n\t}\n\n\t// Drain pending updates before starting polling to avoid 409 Conflict.\n\t// This clears any outstanding long-poll request from a previous instance.\n\tdrainPendingUpdates(token, httpClient)\n\n\treturn b, me, b.Start, nil\n}\n\n// drainPendingUpdates clears any pending updates on Telegram's side by calling\n// getUpdates with offset=-1. This terminates any outstanding long-poll request\n// from a previous bot instance, preventing 409 Conflict errors on restart.\nfunc drainPendingUpdates(token string, httpClient *http.Client) {\n\tapiURL := \"https://api.telegram.org/bot\" + token + \"/getUpdates?offset=-1&timeout=0\"\n\tclient := httpClient\n\tif client == nil {\n\t\tclient = http.DefaultClient\n\t}","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/telegram/telegram.go#L253-L289","documentation":"During bot setup, defaultNewBot calls the Telegram getMe API (with a 10s timeout) to identify the bot. Any getMe failure — invalid token, network problem, Telegram API outage — is wrapped as \"getMe: %w\" so the underlying cause is preserved.","triggerScenarios":"defaultNewBot invoked during Start() when the Telegram Bot API rejects the token (401), is unreachable (DNS/firewall/proxy down), or the 10-second context deadline expires.","commonSituations":"Revoked or mistyped bot token; no outbound internet or blocked access to api.telegram.org; misconfigured proxy; Telegram API regional outage; slow network exceeding the 10s timeout.","solutions":["Verify the bot token with: curl https://api.telegram.org/bot<TOKEN>/getMe","Check network/proxy connectivity to api.telegram.org from the host","If behind a proxy, set the proxy/proxy_username/proxy_password options correctly","Retry after a transient outage — Start's retry loop may recover on reconnect"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"resp, err := http.Get(\"https://api.telegram.org/bot\" + token + \"/getMe\")\n// non-200 or ok=false in the JSON body means the token/network is bad before Start","typeGuard":null,"tryCatchPattern":"if err := plat.Start(handler); err != nil {\n    if strings.Contains(err.Error(), \"getMe:\") {\n        // transient? retry with backoff after checking token/network\n        return retryWithBackoff(func() error { return plat.Start(handler) })\n    }\n    return err\n}","preventionTips":["Validate the token with a getMe curl before deploying","Confirm api.telegram.org reachability (firewall, proxy, DNS)","Provide proxy options if the host requires one","Avoid multiple pollers on the same token to reduce API conflicts"],"tags":["telegram","api","authentication","network"],"backgroundTag":"http-error-response","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"}