yikart/AiToEarn · error · BadRequestException
userId和accountId是必须的
Error message
userId和accountId是必须的
What it means
GET /plat/twitter/timeline derives userId from the authenticated system JWT (@GetToken()) and takes accountId from the query. It throws BadRequestException('userId和accountId是必须的') when either is falsy — i.e. the request was unauthenticated/expired (no systemToken.id) or the accountId query param was omitted. After validation it fetches an access token via getUserAccessToken and calls the timeline service.
Source
Thrown at project/aitoearn-electron/server/src/modules/plat/twitter/twitter.controller.ts:168
/**
* 获取用户的Twitter时间线
*/
@Get('timeline')
@ApiOperation({ summary: '获取用户的Twitter时间线' })
// @ApiQuery({ name: 'userId', required: true, description: '用户ID' })
@ApiQuery({ name: 'accountId', required: true, description: '账号ID' })
@ApiQuery({ name: 'maxResults', required: false, description: '最大结果数', type: 'number' })
async getUserTimeline(
@GetToken() systemToken: TokenInfo,
// @Query('userId') userId: string,
@Query('accountId') accountId: string,
@Query('maxResults') maxResults?: number,
) {
const userId = systemToken.id;
if (!userId || !accountId) {
throw new BadRequestException('userId和accountId是必须的');
}
const accessToken = await this.twitterAuthService.getUserAccessToken(accountId);
return this.twitterService.getUserTimeline(accessToken, userId, accountId, maxResults);
}
/**
* 发布新推文
*/
@Post('tweets/create')
@ApiOperation({ summary: '发布新推文' })
@ApiBody({
schema: {
type: 'object',
properties: {
// userId: { type: 'string', description: '用户ID' },
accountId: { type: 'string', description: 'Twitter账号ID' },View on GitHub (pinned to d3aa8bea5b)
Solutions
- Re-authenticate to get a fresh system JWT and send it in the Authorization header
- Add ?accountId=<id> to the request URL
- Client-side guard: if (!authToken || !accountId) skip/redirect to login
- If 401/empty-token errors follow (errors 450-452), re-authorize the Twitter account itself
Example fix
// before
await api.get('/plat/twitter/timeline');
// after
await api.get('/plat/twitter/timeline', {
params: { accountId },
headers: { Authorization: `Bearer ${systemToken}` },
}); Defensive patterns
Strategy: validation
Validate before calling
if (!systemToken || !accountId) {
redirectToLogin(); // userId comes from the JWT; no token means the 400
}
await api.get('/plat/twitter/timeline', { params: { accountId }, headers: { Authorization: `Bearer ${systemToken}` } }); Type guard
function isTimelineRequest(t: unknown, accountId: unknown): accountId is string {
return !!t && typeof (t as any).id === 'string' && (t as any).id.length > 0
&& typeof accountId === 'string' && accountId.length > 0;
} Try / catch
try {
return await api.get('/plat/twitter/timeline', { params: { accountId } });
} catch (e) {
if (e.response?.status === 400) {
// missing JWT-derived userId or accountId — re-login then retry
await relogin();
return await api.get('/plat/twitter/timeline', { params: { accountId } });
}
throw e;
} Prevention
- Install a request interceptor that always attaches the system JWT
- Redirect to login on 401/expired tokens instead of letting later calls 400
- Only call timeline once an account is selected in the UI
- Remember maxResults is optional and doesn't affect this validation
When it happens
Trigger: Calling /plat/twitter/timeline without an Authorization header or with an expired JWT (userId undefined); omitting ?accountId=...; whitespace-only accountId.
Common situations: Cron jobs/scripts hitting the endpoint without a login token; token expiry mid-session; frontend calling before the selected account id resolves; test tools like curl missing the auth header.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- videoId, userId和accountId是必须的
- token和mail是必须的
- accountId是必须的
- tweetId, userId和accountId是必须的
- Invalid subtitle data: ${z.prettifyError(result.error)}
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/2348abbcce9d4e2f.
Report an issue: GitHub.