yikart/AiToEarn · warning · BadRequestException
只能选择一个参数: allThreadsRelatedToChannelId, id, videoId
Error message
只能选择一个参数: allThreadsRelatedToChannelId, id, videoId
What it means
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.
Source
Thrown at project/aitoearn-electron/server/src/modules/plat/youtube/youtube.controller.ts:314
@ApiOperation({ summary: '获取评论会话列表' })
@Get('commentThreads/list')
async getCommentThreadsList(
@GetToken() token: TokenInfo,
@Query('accountId') accountId: string,
@Query('allThreadsRelatedToChannelId') allThreadsRelatedToChannelId: string,
@Query('id') id: string,
@Query('videoId') videoId: string,
@Query('order') order?: string,
@Query('searchTerms') searchTerms?: string,
@Query('maxResults') maxResults?: string,
@Query('pageToken') pageToken?: string,
) {
// 校验确保只有一个参数传递
const params = [allThreadsRelatedToChannelId, id, videoId];
const nonEmptyParams = params.filter(param => param !== undefined && param !== null && param !== '');
if (nonEmptyParams.length > 1) {
throw new BadRequestException('只能选择一个参数: allThreadsRelatedToChannelId, id, videoId');
}
const accessToken = await this.youtubeAuthService.getUserAccessToken(accountId);
return this.youtubeService.getCommentThreadsList(accessToken, allThreadsRelatedToChannelId, id, videoId, maxResults, pageToken, order, searchTerms);
}
@ApiOperation({ summary: '创建顶级评论' })
@Post('commentThreads/insert')
async commentThreadsInsert(
@GetToken() token: TokenInfo,
@Body('accountId') accountId: string,
@Body('snippet') snippet: Record<string, any>,
) {
const accessToken = await this.youtubeAuthService.getUserAccessToken(accountId);
return this.youtubeService.insertCommentThreads(accessToken, snippet);
}
@ApiOperation({ summary: '获取视频类别列表' })
@Get('video/categories/list')View on GitHub (pinned to d3aa8bea5b)
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
Example fix
// before GET /api/plat/youtube/commentThreads/list?accountId=a&videoId=v1&allThreadsRelatedToChannelId=UC1 // after GET /api/plat/youtube/commentThreads/list?accountId=a&videoId=v1
Defensive patterns
Strategy: validation
Validate before calling
const filters = { allThreadsRelatedToChannelId, id, videoId };
const count = Object.values(filters).filter(v => v !== undefined && v !== null && v !== '').length;
if (count > 1) throw new Error('Provide at most one of allThreadsRelatedToChannelId, id, videoId'); Try / catch
try {
const threads = await api.get('/plat/youtube/commentThreads/list', { params });
} catch (e) {
if (e.response?.status === 400 && String(e.response.data?.message).includes('只能选择一个参数')) {
params = prioritizeFilter(params, ['id', 'videoId', 'allThreadsRelatedToChannelId']);
}
} Prevention
- 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
When it happens
Trigger: GET commentThreads/list with e.g. videoId=vid123 and allThreadsRelatedToChannelId=UCxxx together, or id plus videoId.
Common situations: 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.
Related errors
- 只能选择一个参数: handle, userName, id 或 mine
- 只能选择一个参数: channelId, id, mine
- 只能选择一个参数: regionCode, id
- 邮箱参数不能为空
- Invalid ObjectId
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/795938ead34ebef0.
Report an issue: GitHub.