{"record":{"id":"007ce5108b9d30d0","repo":"chenhg5/cc-connect","slug":"tuitui-team-id-not-found-for-channel-q","errorCode":null,"errorMessage":"tuitui: team_id not found for channel %q","messagePattern":"tuitui: team_id not found for channel %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/tuitui/tuitui.go","lineNumber":222,"sourceCode":"\t}\n\tif strings.TrimSpace(markdown) == \"\" {\n\t\treturn fmt.Errorf(\"tuitui: markdown is required\")\n\t}\n\n\tchatID := channelID\n\tif guessChatType(channelID) == chatTypeChannel {\n\t\tif parentID = strings.TrimSpace(parentID); parentID != \"\" {\n\t\t\ttarget := teamsParseChatID(channelID)\n\t\t\tchatID = teamsBuildChatID(target[\"team_id\"], target[\"channel_id\"], parentID)\n\t\t}\n\t} else {\n\t\tinfo, err := p.getChannelInfo(ctx, channelID)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tteamID := stringFromAny(info[\"team_id\"])\n\t\tif teamID == \"\" {\n\t\t\treturn fmt.Errorf(\"tuitui: team_id not found for channel %q\", channelID)\n\t\t}\n\t\tchatID = teamsBuildChatID(teamID, channelID, strings.TrimSpace(parentID))\n\t}\n\treturn p.sendText(ctx, replyContext{chatID: chatID, chatType: chatTypeChannel}, markdown)\n}\n\nfunc (p *Platform) SendImage(ctx context.Context, replyCtx any, img core.ImageAttachment) error {\n\tname := img.FileName\n\tif name == \"\" {\n\t\tname = \"image\"\n\t}\n\tmediaID, _, err := p.uploadMedia(ctx, img.Data, img.MimeType, name, \"image\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"tuitui: upload image: %w\", err)\n\t}\n\trctx, err := requireReplyContext(replyCtx)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/tuitui/tuitui.go#L204-L240","documentation":"For channel-type IDs, SendChannelPost must translate the channel into a teams chat ID, which requires the owning team's ID. It fetches channel info via getChannelInfo and, if the returned map has no non-empty \"team_id\", fails with this error naming the channel. The channel exists but is not associated with a team the bot can resolve.","triggerScenarios":"Calling SendChannelPost with a channel-type ID whose getChannelInfo response lacks \"team_id\" or returns an empty string for it.","commonSituations":"Posting to a channel whose team membership is not visible to the bot (missing scope or bot not added to the team); stale channel metadata after the channel was moved/archived; API returned partial channel info.","solutions":["Add the bot to the team that owns the channel and grant scopes so channel info includes team_id.","Verify the channel ID is correct and still active by calling getChannelInfo directly and inspecting the response.","Configure an explicit team-to-channel mapping (or pass a fully-qualified teams chat ID) instead of relying on lookup."],"exampleFix":"// before\ninfo, _ := p.GetChannelInfo(ctx, chID) // returns no team_id\np.SendChannelPost(ctx, chID, md, \"\")\n// after\ninfo, err := p.GetChannelInfo(ctx, chID)\nif err != nil || stringFromAny(info[\"team_id\"]) == \"\" {\n    return fmt.Errorf(\"cannot resolve team for channel %s; check bot membership\", chID)\n}\np.SendChannelPost(ctx, chID, md, \"\")","handlingStrategy":"try-catch","validationCode":"info, err := p.GetChannelInfo(ctx, chID)\nif err == nil && stringFromAny(info[\"team_id\"]) == \"\" {\n    return fmt.Errorf(\"team not resolvable for %s\", chID)\n}","typeGuard":"func teamResolvable(info map[string]any) bool {\n    tid, _ := info[\"team_id\"].(string)\n    return tid != \"\"\n}","tryCatchPattern":"if err := p.SendChannelPost(ctx, chID, md, parent); err != nil && strings.Contains(err.Error(), \"team_id not found\") {\n    log.Error(\"bot may not be a member of the owning team\", \"channel\", chID, \"cause\", err)\n}","preventionTips":["Ensure the bot is added to every team whose channels you post to.","Cache and periodically refresh channel→team mappings.","Pre-resolve team IDs during setup and fail fast in config checks."],"tags":["lookup","teams","resource-not-found"],"backgroundTag":"resource-not-found","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"}