binarywang/WxJava · error · WxErrorException
getchatdata err ret + ret
Error message
getchatdata err ret + ret
What it means
Thrown when Finance.GetChatData() returns a non-zero code while fetching the chat-record list from the WeChat archive. This is the first step in the archive pipeline — it retrieves encrypted chat metadata (seq, encrypt_random_key, encrypt_chat_msg) in bulk. A non-zero return means the native SDK rejected the fetch request.
Source
Thrown at weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java:332
}
@Override
public WxCpAgreeInfo checkSingleAgree(@NonNull WxCpCheckAgreeRequest checkAgreeRequest) throws WxErrorException {
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(CHECK_SINGLE_AGREE);
String responseContent = this.cpService.postForMsgAudit(apiUrl, checkAgreeRequest.toJson());
return WxCpAgreeInfo.fromJson(responseContent);
}
@Override
public List<WxCpChatDatas.WxCpChatData> getChatRecords(long seq, @NonNull long limit, String proxy, String passwd,
@NonNull long timeout) throws Exception {
long sdk = this.getOrInitThreadLocalSdk();
long slice = Finance.NewSlice();
long ret = Finance.GetChatData(sdk, seq, limit, proxy, passwd, timeout, slice);
if (ret != 0) {
Finance.FreeSlice(slice);
throw new WxErrorException("getchatdata err ret " + ret);
}
// 拉取会话存档
String content = Finance.GetContentFromSlice(slice);
Finance.FreeSlice(slice);
WxCpChatDatas chatDatas = WxCpChatDatas.fromJson(content);
if (chatDatas.getErrCode().intValue() != 0) {
throw new WxErrorException(chatDatas.toJson());
}
List<WxCpChatDatas.WxCpChatData> chatDataList = chatDatas.getChatData();
return chatDataList != null ? chatDataList : Collections.emptyList();
}
@Override
public WxCpChatModel getDecryptChatData(@NonNull WxCpChatDatas.WxCpChatData chatData,
@NonNull Integer pkcs1) throws Exception {
long sdk = this.getOrInitThreadLocalSdk();View on GitHub (pinned to 1c43293a3c)
Solutions
- Ensure the SDK is initialized via getOrInitThreadLocalSdk() with a valid msgAudit access_token before calling getChatRecords
- Verify the msgAuditSecret and corpId are correct so the access_token refresh succeeds
- If using a proxy, confirm the proxy can reach qyapi.weixin.qq.com
- Reset seq to 0 to re-fetch from the beginning if the archived data range has shifted
- Check native return code 10001 for SDK init failure, 10002 for token issues
Example fix
// before
long sdk = this.getOrInitThreadLocalSdk();
long ret = Finance.GetChatData(sdk, seq, limit, proxy, passwd, timeout, slice);
// after — verify SDK and token are valid before fetching
long sdk = this.getOrInitThreadLocalSdk();
if (sdk == 0) {
throw new WxErrorException("SDK 初始化失败,请检查 access_token 和 Finance.NewSdk");
}
String token = cpService.getMsgAuditAccessToken(false);
if (StringUtils.isBlank(token)) {
throw new WxErrorException("会话存档 access_token 为空,请检查 msgAuditSecret 配置");
}
long ret = Finance.GetChatData(sdk, seq, limit, proxy, passwd, timeout, slice); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate SDK state before fetching chat records
String token = cpService.getMsgAuditAccessToken(false);
if (StringUtils.isBlank(token)) {
throw new IllegalStateException("会话存档 access_token 不可用,请检查 msgAuditSecret");
}
if (seq < 0) {
throw new IllegalArgumentException("seq 不能为负数");
} Try / catch
try {
List<WxCpChatData> records = msgAuditService.getChatRecords(seq, limit, proxy, passwd, timeout);
} catch (WxErrorException e) {
log.error("获取会话存档记录失败 seq={}: {}", seq, e.getMessage());
if (e.getError().getErrorCode() == 10001 || e.getMessage().contains("ret 10001")) {
// SDK init failure — re-initialize and retry once
cpService.getMsgAuditAccessToken(true);
}
throw e;
} Prevention
- Ensure the msgAudit SDK is initialized with Finance.InitSdk() and a valid access_token before the first getChatRecords call
- Persist the last successfully processed seq so you resume correctly after a restart
- Monitor token expiry and refresh proactively rather than waiting for an error
- Run the archive poller on a fixed schedule to avoid large seq gaps
When it happens
Trigger: Calling getChatRecords() with an expired or uninitialized SDK handle, an access_token that has lapsed, a seq value beyond the valid range, network/proxy failures reaching the WeChat archive endpoint, or the SDK's internal state being corrupted (e.g., after a process crash without re-init).
Common situations: The msgAudit access token was never obtained (msgAuditSecret not configured or wrong), the SDK handle was initialized in a previous process run and not re-created, the proxy is misconfigured for the archive endpoint, or seq was persisted from an old session and is now invalid after a gap in polling.
Related errors
AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14).
Data as JSON: /api/errors/7f982dbe9a609272.
Report an issue: GitHub.