{"record":{"id":"795938ead34ebef0","repo":"yikart/AiToEarn","slug":"allthreadsrelatedtochannelid-id-videoi","errorCode":null,"errorMessage":"只能选择一个参数: allThreadsRelatedToChannelId, id, videoId","messagePattern":"只能选择一个参数: allThreadsRelatedToChannelId, id, videoId","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"project/aitoearn-electron/server/src/modules/plat/youtube/youtube.controller.ts","lineNumber":314,"sourceCode":"  @ApiOperation({ summary: '获取评论会话列表' })\n  @Get('commentThreads/list')\n  async getCommentThreadsList(\n    @GetToken() token: TokenInfo,\n    @Query('accountId') accountId: string,\n    @Query('allThreadsRelatedToChannelId') allThreadsRelatedToChannelId: string,\n    @Query('id') id: string,\n    @Query('videoId') videoId: string,\n    @Query('order') order?: string,\n    @Query('searchTerms') searchTerms?: string,\n    @Query('maxResults') maxResults?: string,\n    @Query('pageToken') pageToken?: string,\n    ) {\n    // 校验确保只有一个参数传递\n    const params = [allThreadsRelatedToChannelId, id, videoId];\n    const nonEmptyParams = params.filter(param => param !== undefined && param !== null && param !== '');\n\n    if (nonEmptyParams.length > 1) {\n      throw new BadRequestException('只能选择一个参数: allThreadsRelatedToChannelId, id, videoId');\n    }\n    const accessToken = await this.youtubeAuthService.getUserAccessToken(accountId);\n    return this.youtubeService.getCommentThreadsList(accessToken, allThreadsRelatedToChannelId, id, videoId, maxResults, pageToken, order, searchTerms);\n  }\n\n  @ApiOperation({ summary: '创建顶级评论' })\n  @Post('commentThreads/insert')\n  async commentThreadsInsert(\n    @GetToken() token: TokenInfo,\n    @Body('accountId') accountId: string,\n    @Body('snippet') snippet: Record<string, any>,\n  ) {\n    const accessToken = await this.youtubeAuthService.getUserAccessToken(accountId);\n    return this.youtubeService.insertCommentThreads(accessToken, snippet);\n  }\n\n  @ApiOperation({ summary: '获取视频类别列表' })\n  @Get('video/categories/list')","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/modules/plat/youtube/youtube.controller.ts#L296-L332","documentation":"commentThreads.list requires exactly one filter: allThreadsRelatedToChannelId, id, or videoId. The controller counts non-empty values among these and throws BadRequestException when more than one is present.","triggerScenarios":"GET commentThreads/list with e.g. videoId=vid123 and allThreadsRelatedToChannelId=UCxxx together, or id plus videoId.","commonSituations":"UI with both a channel context and a video context sends both; cached/default query params merged with explicit filters; building the URL by concatenating optional params without resetting previous ones.","solutions":["Pass exactly one of allThreadsRelatedToChannelId, id, videoId per request","Reset other filter keys in client state when switching context (channel vs video vs thread)","Use order/searchTerms freely — they are not part of the exclusivity rule"],"exampleFix":"// before\nGET /api/plat/youtube/commentThreads/list?accountId=a&videoId=v1&allThreadsRelatedToChannelId=UC1\n// after\nGET /api/plat/youtube/commentThreads/list?accountId=a&videoId=v1","handlingStrategy":"validation","validationCode":"const filters = { allThreadsRelatedToChannelId, id, videoId };\nconst count = Object.values(filters).filter(v => v !== undefined && v !== null && v !== '').length;\nif (count > 1) throw new Error('Provide at most one of allThreadsRelatedToChannelId, id, videoId');","typeGuard":null,"tryCatchPattern":"try {\n  const threads = await api.get('/plat/youtube/commentThreads/list', { params });\n} catch (e) {\n  if (e.response?.status === 400 && String(e.response.data?.message).includes('只能选择一个参数')) {\n    params = prioritizeFilter(params, ['id', 'videoId', 'allThreadsRelatedToChannelId']);\n  }\n}","preventionTips":["Match the filter to the context: video page → videoId, channel page → allThreadsRelatedToChannelId, single thread → id","Reset context filters when navigating between channel and video views","order/searchTerms are additive and safe to combine with any single filter"],"tags":["http-400","validation","youtube-api","query-param"],"backgroundTag":"mutually-exclusive-parameters","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}