binarywang/WxJava · warning · WxRuntimeException

用户列表不能为空,不超过 100 个,若用户超过 100 个,请分批获取

Error message

用户列表不能为空,不超过 100 个,若用户超过 100 个,请分批获取

What it means

Thrown (as unchecked WxRuntimeException) by getCheckinData() when the userIdList parameter is null or exceeds 100 entries. This is a pre-flight validation before the HTTP call to WeChat's checkin-data API, which itself enforces the same limit server-side.

Source

Thrown at weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java:48

public class WxCpOaServiceImpl implements WxCpOaService {
  private final WxCpService mainService;

  private static final int MONTH_SECONDS = 31 * 24 * 60 * 60;
  private static final int USER_IDS_LIMIT = 100;

  @Override
  public String apply(WxCpOaApplyEventRequest request) throws WxErrorException {
    String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(APPLY_EVENT),
      request.toJson());
    return GsonParser.parse(responseContent).get("sp_no").getAsString();
  }

  @Override
  public List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, @NonNull Date startTime,
                                              @NonNull Date endTime,
                                              List<String> userIdList) throws WxErrorException {
    if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) {
      throw new WxRuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取");
    }

    long endTimestamp = endTime.getTime() / 1000L;
    long startTimestamp = startTime.getTime() / 1000L;

    if (endTimestamp - startTimestamp < 0 || endTimestamp - startTimestamp > MONTH_SECONDS) {
      throw new WxRuntimeException("获取记录时间跨度不超过一个月");
    }

    JsonObject jsonObject = new JsonObject();
    JsonArray jsonArray = new JsonArray();

    jsonObject.addProperty("opencheckindatatype", openCheckinDataType);
    jsonObject.addProperty("starttime", startTimestamp);
    jsonObject.addProperty("endtime", endTimestamp);

    for (String userid : userIdList) {
      jsonArray.add(userid);

View on GitHub (pinned to 1c43293a3c)

Solutions

  1. Split the user list into batches of at most 100 and call getCheckinData() per batch
  2. Guard against null at the call site by initializing userIdList to an empty list or Collections.emptyList() when no users are needed
  3. Add a pre-call validation utility that chunks lists: Lists.partition(userIdList, 100)

Example fix

// before
List<WxCpCheckinData> data = oaService.getCheckinData(type, start, end, allUserIds); // allUserIds.size() = 250

// after — batch in groups of 100
List<WxCpCheckinData> allData = new ArrayList<>();
for (List<String> batch : Lists.partition(allUserIds, 100)) {
  allData.addAll(oaService.getCheckinData(type, start, end, batch));
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate before calling getCheckinData
if (userIdList == null || userIdList.isEmpty()) {
  throw new IllegalArgumentException("userIdList 不能为 null 或空");
}
if (userIdList.size() > 100) {
  // Batch automatically
  List<List<String>> batches = Lists.partition(userIdList, 100);
  // iterate batches...
}

Prevention

When it happens

Trigger: Passing null for userIdList, or passing a list with more than 100 user IDs to getCheckinData(). The check is `userIdList == null || userIdList.size() > 100`.

Common situations: Fetching checkin data for an entire department without paginating the user list; passing null because the caller forgot to populate the list; a downstream system providing a dynamically-sized list that occasionally exceeds 100.

Related errors


AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14). Data as JSON: /api/errors/bdf2239e6d400a20. Report an issue: GitHub.