yikart/AiToEarn · warning · BadRequestException
只能选择一个参数: channelId, playListIds, mine
Error message
只能选择一个参数: channelId, playListIds, mine
What it means
The getPlayList endpoint accepts three mutually-exclusive modes: `channelId` (lists a channel's playlists), `playListIds` (fetch specific playlists), or `mine=true` (list the authenticated user's playlists). The controller counts non-empty params and throws BadRequestException if more than one is supplied, mirroring how the YouTube Data API requires a single filter. This is thrown before the Google API call.
Source
Thrown at project/aitoearn-electron/server/src/modules/plat/youtube/youtube.controller.ts:442
}
@ApiOperation({ summary: '获取播放列表' })
@Get('playlist/list')
async getPlayList(
@GetToken() token: TokenInfo,
@Query('accountId') accountId: string,
@Query('channelId') channelId?: string,
@Query('id') playListIds?: string,
@Query('mine') mine?: boolean,
@Query('maxResults') maxResults?: string,
@Query('pageToken') pageToken?: string,
) {
// 校验确保只有一个参数传递
const params = [channelId, playListIds, mine];
const nonEmptyParams = params.filter(param => param !== undefined && param !== null && param !== '');
if (nonEmptyParams.length > 1) {
throw new BadRequestException('只能选择一个参数: channelId, playListIds, mine');
}
const accessToken = await this.youtubeAuthService.getUserAccessToken(accountId);
return this.youtubeService.getPlayList(accessToken, channelId, playListIds, mine, maxResults, pageToken);
}
@ApiOperation({ summary: '更新播放列表' })
@Post('playlist/update')
async playlistUpdate(
@GetToken() token: TokenInfo,
@Body('accountId') accountId: string,
@Body('playListId') playListId: string,
@Body('snippet') snippet?: Record<string, any>,
@Body('status') status?: Record<string, any>,
) {
const accessToken = await this.youtubeAuthService.getUserAccessToken(accountId);
return this.youtubeService.updatePlayList(accessToken, playListId, snippet, status);
}
View on GitHub (pinned to d3aa8bea5b)
Solutions
- Pass exactly one of channelId, playListIds, mine per request; remove the others.
- Add client-side logic that clears the other fields when one mode is selected.
- Split needs into multiple calls (one per mode) and merge results in the client.
- Check the request URL/interceptor logs for stale default params like mine=true.
Example fix
// before client.getPlayList(accountId, channelId, playListIds, true); // after client.getPlayList(accountId, playListIds ? undefined : channelId, playListIds, playListIds ? undefined : true);
Defensive patterns
Strategy: validation
Validate before calling
const modes = [channelId, playListIds, mine].filter(v => v !== undefined && v !== null && v !== '');
if (modes.length !== 1) throw new Error('Exactly one of channelId, playListIds, mine must be set'); Type guard
type PlaylistQuery = { channelId?: string } | { playListIds?: string[] } | { mine?: boolean };
function isSingleModeQuery(q: PlaylistQuery): boolean {
return Object.values(q).filter(v => v !== undefined && v !== null && v !== '').length === 1;
} Try / catch
try {
return await client.getPlayList(accountId, undefined, undefined, true);
} catch (e) {
if (String(e.message).includes('只能选择一个参数')) console.error('Playlist query mixed modes; fix caller');
throw e;
} Prevention
- Model the request as a discriminated union so only one mode is expressible.
- Clear sibling fields when one mode is selected in UI.
- Intercept and inspect outgoing URLs in dev to catch stale defaults like mine=true.
- Write a unit test asserting the param-builder emits exactly one mode.
When it happens
Trigger: Calling the playlists endpoint with e.g. ?channelId=UC...&mine=true, or ?playListIds=PL1&mine=true — any combination of two or three of channelId/playListIds/mine that are non-empty (undefined/null/'' filtered out).
Common situations: Clients defaulting `mine` to a truthy value while also passing a channelId; bulk fetch code appending both playListIds and a channel filter; copy-pasted curl commands retaining params from a previous example.
Related errors
- 只能选择一个参数: id, myRating
- 只能选择一个参数: playlistId, playlistItemsIds
- No response from Gemini
- video duration is required
- DashScope HappyHorse does not support image_tail
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/a6c1a7399a8d4bc1.
Report an issue: GitHub.