yikart/AiToEarn · error · BadRequestException
userId, accountId和text是必须的
Error message
userId, accountId和text是必须的
What it means
POST /plat/twitter/tweets/create publishes a tweet. userId comes from the authenticated system JWT while accountId, text, and optional mediaIds come from the JSON body. When userId, accountId, or text is missing/empty the controller throws BadRequestException('userId, accountId和text是必须的'). Note empty string '' is falsy, so blank tweet text also triggers this error.
Source
Thrown at project/aitoearn-electron/server/src/modules/plat/twitter/twitter.controller.ts:203
// userId: { type: 'string', description: '用户ID' },
accountId: { type: 'string', description: 'Twitter账号ID' },
text: { type: 'string', description: '推文内容' },
mediaIds: { type: 'array', items: { type: 'string' }, description: '媒体ID列表(可选)' }
},
required: ['userId', 'accountId', 'text']
}
})
@HttpCode(201)
async createTweet(
@GetToken() systemToken: TokenInfo,
// @Body('userId') userId: string,
@Body('accountId') accountId: string,
@Body('text') text: string,
@Body('mediaIds') mediaIds?: string[],
) {
const userId = systemToken.id;
if (!userId || !accountId || !text) {
throw new BadRequestException('userId, accountId和text是必须的');
}
const accessToken = await this.twitterAuthService.getUserAccessToken(accountId);
return this.twitterService.createTweet(accessToken, userId, accountId, text, mediaIds);
}
/**
* 上传媒体文件
*/
@Post('media/upload')
@ApiOperation({ summary: '上传媒体文件' })
@ApiConsumes('multipart/form-data')
@ApiBody({
schema: {
type: 'object',
properties: {
userId: { type: 'string' },
accountId: { type: 'string' },View on GitHub (pinned to d3aa8bea5b)
Solutions
- Ensure the request carries a valid JWT and JSON body {"accountId":"...","text":"..."} with Content-Type: application/json
- Validate text is a non-empty string client-side before calling (trim and length-check)
- If attaching media, upload first via POST /plat/twitter/media/upload then pass mediaIds along with text
- Re-login if the JWT expired so userId resolves
Example fix
// before
await api.post('/plat/twitter/tweets/create', { accountId, text: content.trim() ? content : undefined });
// after
if (!content.trim()) throw new Error('Tweet text is required');
await api.post('/plat/twitter/tweets/create', { accountId, text: content, mediaIds }, { headers: { 'Content-Type': 'application/json' } }); Defensive patterns
Strategy: validation
Validate before calling
const text = (content ?? '').trim();
if (!systemToken || !accountId || !text) {
throw new Error('Tweet requires an authenticated user, accountId and non-empty text');
}
await api.post('/plat/twitter/tweets/create', { accountId, text, mediaIds }); Type guard
function isCreateTweetBody(b: unknown): b is { accountId: string; text: string; mediaIds?: string[] } {
const x = b as any;
return !!x && typeof x.accountId === 'string' && x.accountId.length > 0
&& typeof x.text === 'string' && x.text.trim().length > 0
&& (x.mediaIds === undefined || (Array.isArray(x.mediaIds) && x.mediaIds.every(i => typeof i === 'string')));
} Try / catch
try {
return await api.post('/plat/twitter/tweets/create', body);
} catch (e) {
if (e.response?.status === 400) {
console.error('createTweet rejected: ensure valid JWT and a JSON body with accountId and non-empty text');
}
throw e;
} Prevention
- Block empty posts in the composer UI before dispatching
- Always send Content-Type: application/json with the body
- Upload media via /media/upload first and pass mediaIds with text — text cannot be empty even for media-only posts
- Refresh expired JWTs so systemToken.id always resolves
When it happens
Trigger: Unauthenticated/expired request (no systemToken.id); body missing accountId or text; text sent as empty string; body not sent as JSON so @Body() fields are all undefined; calling with mediaIds-only content and no text.
Common situations: Composer UI allowing an empty post; file uploads not accepted by the text-only endpoint (use /media/upload separately); automation scripts with malformed JSON or missing Content-Type: application/json; expired session JWT.
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
- tweetId, rating和accountId是必须的
- No response from Gemini
- HTTP ${response.status}
- Failed to get image dimensions
- AiCallFailed
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/162b6a5e23947754.
Report an issue: GitHub.