yikart/AiToEarn · error · BadRequestException

参数错误: rating必须为like或unlike

Error message

参数错误: rating必须为like或unlike

What it means

Thrown by rateTweet after the required-params guard passes, when the supplied rating is not exactly 'like' or 'unlike'. The endpoint maps rating to the corresponding Twitter like/unlike API call, so any other value (including different casing like 'Like') is rejected with this 400.

Source

Thrown at project/aitoearn-electron/server/src/modules/plat/twitter/twitter.controller.ts:374

      },
      required: ['accountId', 'tweetId', 'rating']
    }
  })
  async rateTweet(
    @GetToken() systemToken: TokenInfo,
    @Body('tweetId') tweetId: string,
    @Body('accountId') accountId: string,
    @Body('rating') rating: string,
  ) {
    const userId = systemToken.id;
    if (!tweetId || !userId || !accountId || ! rating) {
      throw new BadRequestException('tweetId, rating和accountId是必须的');
    }

    const accessToken = await this.twitterAuthService.getUserAccessToken(accountId);
    // 在方法开始处验证
    if (!["like", "unlike"].includes(rating)) {
        throw new BadRequestException('参数错误: rating必须为like或unlike');
    }

    // 后续处理
    if (rating === "like") {
        return this.twitterService.likeTweet(accessToken, userId, accountId, tweetId);
    } else {
        return this.twitterService.unlikeTweet(accessToken, userId, accountId, tweetId);
    }
  }

}

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Send rating exactly as the lowercase string 'like' or 'unlike'.
  2. Normalize the client value with toLowerCase() before sending.
  3. Map boolean/numeric UI state to the two accepted strings at the call site.
  4. Consider accepting an enum validated by a Nest DTO (class-validator @IsIn(['like','unlike'])) for earlier, clearer errors.

Example fix

// before
await api.post('/twitter/tweet/rate', { tweetId, accountId, rating: isLiked });
// after
await api.post('/twitter/tweet/rate', { tweetId, accountId, rating: isLiked ? 'like' : 'unlike' });
Defensive patterns

Strategy: validation

Validate before calling

const RATING_VALUES = ['like', 'unlike'] as const;
type Rating = typeof RATING_VALUES[number];
if (!RATING_VALUES.includes(rating as Rating)) throw new Error('rating必须为like或unlike');

Type guard

function isRating(v: unknown): v is 'like' | 'unlike' {
  return v === 'like' || v === 'unlike';
}

Try / catch

try {
  await api.post('/twitter/tweet/rate', { tweetId, accountId, rating });
} catch (e) {
  if (e.response?.status === 400 && e.response.data?.message?.includes('like或unlike')) {
    rating = rating === 'like' ? 'unlike' : 'like'; // or fix the value source
  }
}

Prevention

When it happens

Trigger: POST to rateTweet with rating set to e.g. 'unLike', 'LIKE', 'favorite', a numeric flag, or undefined-adjacent whitespace string.

Common situations: Client uses boolean-like values (1/0, true/false) instead of the strings; legacy API version used different rating vocabulary; casing mismatch after refactoring.

Understand the failure class

Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.

Related errors


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