{"record":{"id":"6aa7ec206439920b","repo":"chenhg5/cc-connect","slug":"tuitui-team-id-is-required-for-channel-history","errorCode":null,"errorMessage":"tuitui: team_id is required for channel history","messagePattern":"tuitui: team_id is required for channel history","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/tuitui/history.go","lineNumber":105,"sourceCode":"\tparsed := map[string]string{}\n\tif strings.HasPrefix(chatID, \"teams_\") {\n\t\tparsed = teamsParseChatID(chatID)\n\t} else {\n\t\tparsed[\"channel_id\"] = chatID\n\t}\n\tchannelID := firstNonEmpty(parsed[\"channel_id\"], chatID)\n\tteamID := parsed[\"team_id\"]\n\tsubject := \"\"\n\tif teamID == \"\" {\n\t\tinfo, err := p.getChannelInfo(ctx, channelID)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tteamID = stringFromAny(info[\"team_id\"])\n\t\tsubject = stringFromAny(info[\"name\"])\n\t}\n\tif teamID == \"\" {\n\t\treturn nil, fmt.Errorf(\"tuitui: team_id is required for channel history\")\n\t}\n\tlimit := opts.Limit\n\tif limit <= 0 {\n\t\tlimit = 20\n\t}\n\tlimit = minInt(100, maxInt(1, limit))\n\torder := \"asc\"\n\tif opts.OrderAsc != nil && !*opts.OrderAsc {\n\t\torder = \"desc\"\n\t}\n\tpayload := map[string]any{\n\t\t\"channel_id\": channelID,\n\t\t\"team_id\":    teamID,\n\t\t\"size\":       limit,\n\t\t\"sort_type\":  \"reply\",\n\t\t\"order\":      order,\n\t}\n\tif opts.RelativeTime != \"\" {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/tuitui/history.go#L87-L123","documentation":"Channel history fetching requires a team_id to scope the query, and it could not be determined. fetchChannelHistory first tries the caller-supplied team ID or, failing that, derives it from the channel info API (channel's team_id field); if both are empty the request cannot proceed and is rejected.","triggerScenarios":"Calling FetchHistory with chatType=\"channel\" for a channel whose /robot/teams/channel/info response lacks team_id (info nil or field absent), and no team_id was provided in options.","commonSituations":"Bot lacks permission to read the channel's metadata so info comes back empty; channel ID mistyped pointing to a nonexistent channel; upstream API changed the info payload shape (e.g. renamed field) breaking stringFromAny extraction.","solutions":["Ensure the bot has read access to the channel so channel info returns team_id.","Verify the channel_id is correct by fetching channel info first and inspecting the payload.","Pass/derive team_id explicitly in the caller if the channel-info endpoint no longer returns it.","Log the raw channel-info JSON to check the field name is still \"team_id\"."],"exampleFix":"// before\nres, err := p.FetchHistory(ctx, channelID, \"channel\", HistoryOptions{})\n// after\nres, err := p.FetchHistory(ctx, channelID, \"channel\", HistoryOptions{TeamID: knownTeamID})","handlingStrategy":"validation","validationCode":"info, err := p.getChannelInfo(ctx, channelID)\nif err != nil { return err }\nteamID := stringFromAny(info[\"team_id\"])\nif teamID == \"\" { return fmt.Errorf(\"cannot resolve team_id for channel %s\", channelID) }","typeGuard":"func channelInfoHasTeam(info map[string]any) bool {\n    return info != nil && stringFromAny(info[\"team_id\"]) != \"\"\n}","tryCatchPattern":"res, err := p.FetchHistory(ctx, channelID, \"channel\", opts)\nif err != nil && strings.Contains(err.Error(), \"team_id is required\") {\n    slog.Warn(\"channel team_id unavailable; check bot channel access\", \"channel\", channelID)\n}","preventionTips":["Confirm bot read access to the channel before history calls","Cache team_id from a known-good channel info response","Pass team_id explicitly when your integration already knows it","Log raw channel-info payloads when upgrading to catch API shape changes"],"tags":["tuitui","channel","validation"],"backgroundTag":"missing-required-argument","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"}