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

  1. Read the appended constraint message after '参数验证失败: ' to see the first failing rule and fix the client payload accordingly.
  2. Ensure the frontend sends exactly the fields/types declared in the DTO; mark truly optional fields with @IsOptional.
  3. Check for recently changed DTOs and update client code to match the new contract.
  4. 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

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


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/b8b5578611b8f302. Report an issue: GitHub.