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
- Split the user list into batches of at most 100 and call getCheckinData() per batch
- Guard against null at the call site by initializing userIdList to an empty list or Collections.emptyList() when no users are needed
- 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
- Always pre-validate list sizes against the 100-user limit before calling OA APIs
- Use Lists.partition(userIdList, 100) (Guava) or a equivalent utility to batch automatically
- Build a shared OA helper that encapsulates batching for all getCheckin*/getApproval* methods
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
- 获取记录时间跨度不超过一个月
- size参数错误,请使用[1-100]填充,默认100
- 受限于网络传输,起止时间的最大跨度为30天,如超过30天,则以结束时间为基准向前取30天进行查询
- 微信开放平台 appId 不能为空
- 微信开放平台 secret 不能为空
AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14).
Data as JSON: /api/errors/bdf2239e6d400a20.
Report an issue: GitHub.