yikart/AiToEarn · error · BadRequestException
参数验证失败:
Error message
参数验证失败:
What it means
NestJS ValidationPipe built on class-validator. transform() validates the incoming DTO; when class-validator reports constraint violations it logs the first error and throws a BadRequestException with the message '参数验证失败: <first constraint message>'. Thrown whenever request payload fails DTO validation.
Source
Thrown at project/aitoearn-electron/server/src/validation.pipe.ts:40
return !types.includes(metatype);
}
async transform(value: any, { metatype }: ArgumentMetadata) {
if (!metatype || !this.toValidate(metatype)) return value;
// 数据转换成类
const inData: any = plainToClass(metatype, value, {
excludeExtraneousValues: true,
});
const errors = validateSync(inData, {
whitelist: true,
});
if (errors.length <= 0) return inData;
console.log('------ 参数验证失败:', _.values(errors[0].constraints)[0]);
throw new BadRequestException(
'参数验证失败: ' + _.values(errors[0].constraints)[0],
);
}
}
View on GitHub (pinned to d3aa8bea5b)
Solutions
- Read the appended constraint message after '参数验证失败: ' to see the first failing rule and fix the client payload accordingly.
- Ensure the frontend sends exactly the fields/types declared in the DTO; mark truly optional fields with @IsOptional.
- Check for recently changed DTOs and update client code to match the new contract.
- If nested objects are validated incorrectly, verify @ValidateNested and @Type() decorators are present.
Example fix
// before
axios.post('/api/x', { title: 123 })
// after
axios.post('/api/x', { title: 'valid string' }) // or add @IsOptional to the DTO field Defensive patterns
Strategy: validation
Validate before calling
// client-side mirror of the DTO before sending
function validatePayload(p: Record<string, unknown>, required: string[]): string | null {
const missing = required.filter(k => p[k] === undefined || p[k] === null || p[k] === '')
return missing.length ? `缺少必填字段: ${missing.join(', ')}` : null
} Type guard
function isPlainObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v)
} Try / catch
try {
await axios.post(url, payload)
}
catch (e) {
if (e?.response?.status === 400 && String(e.response.data?.message || '').startsWith('参数验证失败')) {
console.warn('字段校验失败:', e.response.data.message)
}
else throw e
} Prevention
- Keep frontend types in sync with backend DTOs (share schemas or generate from OpenAPI).
- Always send strings as strings and numbers as numbers per the DTO.
- Mark truly optional fields with @IsOptional server-side.
- Log the full message after '参数验证失败: ' — it names the first failing constraint.
When it happens
Trigger: Any HTTP request whose body/query/params violate the route's DTO decorators (@IsString, @IsNotEmpty, @Min, etc.), e.g. missing required field, wrong type, or string exceeding @MaxLength.
Common situations: Frontend sending undefined/null fields not marked @IsOptional; sending numbers as strings; API contract drift after a DTO change; clients omitting fields after backend added new validation rules.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- imageSize must be one of 1K, 2K, or 4K
- Invalid ObjectId
- userId, accountId和file是必须的
- tweetId, userId和accountId是必须的
- userId, accountId和query是必须的
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/b8b5578611b8f302.
Report an issue: GitHub.