{"record":{"id":"10db54ffb8ebcdd9","repo":"chenhg5/cc-connect","slug":"tuitui-channel-info-errcode-d-errmsg-s","errorCode":null,"errorMessage":"tuitui: channel info errcode=%d errmsg=%s","messagePattern":"tuitui: channel info errcode=(.+?) errmsg=(.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/tuitui/history.go","lineNumber":254,"sourceCode":"\t\t}\n\t\tout = append(out, item)\n\t}\n\treturn out\n}\n\nfunc (p *Platform) getChannelInfo(ctx context.Context, channelID string) (map[string]any, error) {\n\tvar out struct {\n\t\tErrCode int    `json:\"errcode\"`\n\t\tErrMsg  string `json:\"errmsg\"`\n\t\tDatas   struct {\n\t\t\tInfo map[string]any `json:\"info\"`\n\t\t} `json:\"datas\"`\n\t}\n\tif err := p.postJSON(ctx, \"/robot/teams/channel/info\", map[string]any{\"channel_id\": channelID}, &out); err != nil {\n\t\treturn nil, err\n\t}\n\tif out.ErrCode != 0 {\n\t\treturn nil, fmt.Errorf(\"tuitui: channel info errcode=%d errmsg=%s\", out.ErrCode, out.ErrMsg)\n\t}\n\treturn out.Datas.Info, nil\n}\n\nfunc formatPostThreads(posts []map[string]any) []string {\n\tthreads := make([]string, 0, len(posts))\n\tfor _, postThread := range posts {\n\t\tvar items []map[string]any\n\t\tif topic, _ := postThread[\"topic\"].(map[string]any); topic != nil {\n\t\t\titems = append(items, topic)\n\t\t}\n\t\tif replies, _ := postThread[\"reply_list\"].([]any); len(replies) > 0 {\n\t\t\tfor i := len(replies) - 1; i >= 0; i-- {\n\t\t\t\tif reply, _ := replies[i].(map[string]any); reply != nil {\n\t\t\t\t\titems = append(items, reply)\n\t\t\t\t}\n\t\t\t}\n\t\t}","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/tuitui/history.go#L236-L272","documentation":"The TuiTui channel info API (/robot/teams/channel/info) returned a non-zero errcode, so the channel's metadata (team_id, name) could not be retrieved. This function underpins both channel history fetching and SendChannelPost, so both fail when it errors.","triggerScenarios":"getChannelInfo called by fetchChannelHistory or SendChannelPost where the response body carries out.ErrCode != 0 — typically channel_id not found, bot lacks channel access, or an invalid/expired token.","commonSituations":"Channel deleted or ID mistyped; bot removed from the channel/team; token refresh lapse; sending a post to a channel the bot was never invited to.","solutions":["Read errmsg to identify the backend reason (not-found vs permission vs auth).","Verify the channel_id exists and the bot has access to that channel/team.","Refresh the bot token if the errcode indicates auth failure.","For SendChannelPost failures, check the bot was invited to the channel before posting."],"exampleFix":"// before\nif out.ErrCode != 0 {\n    return nil, fmt.Errorf(\"tuitui: channel info errcode=%d errmsg=%s\", out.ErrCode, out.ErrMsg)\n}\n// after\nif out.ErrCode == errChannelNotFound {\n    return nil, fmt.Errorf(\"tuitui: channel %s not found or no access: check bot membership\", channelID)\n}\nreturn nil, fmt.Errorf(\"tuitui: channel info errcode=%d errmsg=%s\", out.ErrCode, out.ErrMsg)","handlingStrategy":"try-catch","validationCode":"if channelID == \"\" { return fmt.Errorf(\"channel id required\") }\n// ensure bot invited to channel/team before calling SendChannelPost","typeGuard":"func (p *Platform) channelAccessible(ctx context.Context, id string) bool {\n    _, err := p.getChannelInfo(ctx, id)\n    return err == nil\n}","tryCatchPattern":"info, err := p.getChannelInfo(ctx, channelID)\nif err != nil {\n    var apiErr *TuiTuiAPIError\n    if errors.As(err, &apiErr) && apiErr.IsAuth() {\n        if rerr := p.refreshToken(ctx); rerr == nil {\n            info, err = p.getChannelInfo(ctx, channelID)\n        }\n    }\n    if err != nil { return fmt.Errorf(\"cannot access channel %s: %w\", channelID, err) }\n}","preventionTips":["Validate channel IDs at config load with a getChannelInfo probe","Invite the bot to the team/channel before programmatic posting","Refresh tokens proactively before long-running operations","Map errcodes to user-actionable messages (not-found, permission, auth)"],"tags":["tuitui","api","channel"],"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-14T00:17:10.932Z"}