{"record":{"id":"7e9e1b676310928c","repo":"chenhg5/cc-connect","slug":"telegram-setmycommands-failed-w","errorCode":null,"errorMessage":"telegram: setMyCommands failed: %w","messagePattern":"telegram: setMyCommands failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"platform/telegram/telegram.go","lineNumber":1719,"sourceCode":"\t\ttgCommands = append(tgCommands, models.BotCommand{\n\t\t\tCommand:     cmd,\n\t\t\tDescription: desc,\n\t\t})\n\t}\n\n\t// Limit to 100 commands\n\tif len(tgCommands) > 100 {\n\t\ttgCommands = tgCommands[:100]\n\t}\n\n\tif len(tgCommands) == 0 {\n\t\tslog.Debug(\"telegram: no commands to register\")\n\t\treturn nil\n\t}\n\n\tctx := context.Background()\n\tif _, err := bot.SetMyCommands(ctx, &tgbot.SetMyCommandsParams{Commands: tgCommands}); err != nil {\n\t\treturn fmt.Errorf(\"telegram: setMyCommands failed: %w\", err)\n\t}\n\n\tslog.Info(\"telegram: registered bot commands\", \"count\", len(tgCommands))\n\treturn nil\n}\n\n// extractEntityText extracts a substring from text using Telegram's UTF-16 code unit\n// offset and length. Telegram Bot API entity offsets are measured in UTF-16 code units,\n// not bytes or Unicode code points, so direct byte slicing produces wrong results\n// when the text contains non-ASCII characters (e.g. Chinese, emoji).\nfunc extractEntityText(text string, offsetUTF16, lengthUTF16 int) string {\n\tencoded := utf16.Encode([]rune(text))\n\tendUTF16 := offsetUTF16 + lengthUTF16\n\tif offsetUTF16 < 0 || lengthUTF16 < 0 || endUTF16 > len(encoded) {\n\t\treturn \"\"\n\t}\n\treturn string(utf16.Decode(encoded[offsetUTF16:endUTF16]))\n}","sourceCodeStart":1701,"sourceCodeEnd":1737,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/telegram/telegram.go#L1701-L1737","documentation":"Registering the bot's command list via Telegram's setMyCommands API failed. This is called at startup (or config reload) to make slash-commands appear in the bot's UI menu. The error wraps the underlying Bot API error; the commands may not be registered so the client menu will be stale or empty.","triggerScenarios":"Calling setMyCommands with a command list Telegram rejects: command names not matching ^[a-z0-9_]+$ or longer than 32 chars, more than 100 commands, descriptions exceeding 256 chars, or an invalid/expired bot token making the API call fail.","commonSituations":"Bot token misconfigured or revoked; a newly added command name contains uppercase or hyphens; description too long after editing config; Telegram API outage or rate limit at startup.","solutions":["Validate command names (lowercase letters, digits, underscore, ≤32 chars) and descriptions (≤256 chars) before calling.","Verify the bot token is valid — run getMe with the same token.","Check the wrapped cause: 401 = bad token, 400 = invalid command payload, 429 = rate limited (retry after).","This error is usually non-fatal at startup; consider logging a warning instead of aborting registration."],"exampleFix":"// before\nreturn fmt.Errorf(\"telegram: setMyCommands failed: %w\", err)\n// after\nslog.Warn(\"telegram: setMyCommands failed; command menu may be stale\", \"err\", err)\nreturn nil // non-fatal: bot still works without registered menu","handlingStrategy":"fallback","validationCode":"for _, c := range cmds {\n    if len(c.Command) > 32 || !regexp.MustCompile(`^[a-z0-9_]+$`).MatchString(c.Command) {\n        return fmt.Errorf(\"invalid command name %q\", c.Command)\n    }\n    if len(c.Description) > 256 { return fmt.Errorf(\"description too long for %q\", c.Command) }\n}","typeGuard":null,"tryCatchPattern":"if err := registerCommands(ctx, bot, cmds); err != nil {\n    slog.Warn(\"telegram: command registration failed, continuing\", \"err\", err)\n}","preventionTips":["Keep command names lowercase snake_case and short","Validate descriptions length at config load time","Treat command registration as best-effort, not startup-fatal","Periodically verify token validity with getMe"],"tags":["telegram","bot-api","configuration"],"backgroundTag":"api-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"}