yikart/AiToEarn · warning · AppException
AiCallFailed
AiCallFailed
Error message
Missing usage metadata
What it means
postComment validates TikTokCommentDto fields accountId, videoId and text; any missing/empty field throws BadRequestException('accountId, videoId和text是必须的'). All three are needed to resolve the token, target video, and comment content.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/chat/chat.service.ts:143
}
async chatCompletion(request: ChatCompletionDto, userId: string) {
const { messages, model, ...params } = request
const langchainMessages: BaseMessage[] = messages.map((message) => {
return new ChatMessage(message)
})
const result = await this.openaiService.createChatCompletion({
model,
messages: langchainMessages,
...params,
modalities: params.modalities as OpenAIClient.Chat.ChatCompletionModality[],
})
const usage = result.usage_metadata
if (!usage) {
throw new AppException(ResponseCode.AiCallFailed, { error: 'Missing usage metadata' })
}
// 处理返回的 content 中的 base64 图片
result.content = await this.processAIMessageChunkContent(result.content, model, userId) as typeof result.content
return {
model,
usage,
...result,
}
}
private async handleCompletion(
params: ChatCompletionDto,
userId: string,
userType: UserType,
modelConfig: { name: string, channel: AiLogChannel },
startedAt: Date,View on GitHub (pinned to d3aa8bea5b)
Solutions
- Send { accountId, videoId, text } with non-empty text in the JSON body.
- Disable the submit button until text.trim().length > 0 client-side.
- Verify the DTO key is exactly 'text' matching TikTokCommentDto.
Example fix
// before
await api.post('/plat/tiktok/video/comment', { accountId, videoId, text });
// after
if (!accountId || !videoId || !text?.trim()) return;
await api.post('/plat/tiktok/video/comment', { accountId, videoId, text: text.trim() }); Defensive patterns
Strategy: validation
Validate before calling
if (!commentDto.accountId || !commentDto.videoId || !commentDto.text?.trim()) throw new Error('accountId, videoId和text是必须的'); Type guard
function isCommentDto(v): v is { accountId: string; videoId: string; text: string } {
const d = v as any;
return typeof d?.accountId === 'string' && d.accountId.length > 0 && typeof d?.videoId === 'string' && d.videoId.length > 0 && typeof d?.text === 'string' && d.text.trim().length > 0;
} Try / catch
try {
return await api.post('/plat/tiktok/video/comment', commentDto);
} catch (e) {
if (e.response?.status === 400) console.error('评论请求缺少 accountId/videoId/text');
throw e;
} Prevention
- Disable the comment submit button until text is non-empty
- Trim text before sending and validate the DTO key is 'text'
- Validate all three fields client-side before issuing the request
When it happens
Trigger: POST the comment route with a TikTokCommentDto body where accountId, videoId or text is absent or an empty string (e.g. submitting the comment box without typing text).
Common situations: User submits an empty comment and the frontend doesn't block it, comment payload built from a context missing the account, or DTO field name mismatch (comment vs text) leaving text undefined.
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
- No response from Gemini
- HTTP ${response.status}
- Failed to get image dimensions
- tweetId, rating和accountId是必须的
- No subtitle entries in response
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/7683e29ec6d6e8c7.
Report an issue: GitHub.