binarywang/WxJava · error · WxErrorException

会话存档secret未配置

Error message

会话存档secret未配置

What it means

Thrown (as checked WxErrorException) by getMsgAuditAccessToken() in the Apache HttpClient implementation when the chat-archive secret (会话存档secret) is null or blank. This secret is required to obtain a dedicated access_token for the message-audit (会话存档) Finance SDK.

Source

Thrown at weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java:139

  }

  @Override
  public String getMsgAuditAccessToken(boolean forceRefresh) throws WxErrorException {
    if (!this.configStorage.isMsgAuditAccessTokenExpired() && !forceRefresh) {
      return this.configStorage.getMsgAuditAccessToken();
    }

    Lock lock = this.configStorage.getMsgAuditAccessTokenLock();
    lock.lock();
    try {
      // 拿到锁之后,再次判断一下最新的token是否过期,避免重刷
      if (!this.configStorage.isMsgAuditAccessTokenExpired() && !forceRefresh) {
        return this.configStorage.getMsgAuditAccessToken();
      }
      // 使用会话存档secret获取access_token
      String msgAuditSecret = this.configStorage.getMsgAuditSecret();
      if (msgAuditSecret == null || msgAuditSecret.trim().isEmpty()) {
        throw new WxErrorException("会话存档secret未配置");
      }
      String url = String.format(this.configStorage.getApiUrl(WxCpApiPathConsts.GET_TOKEN),
        this.configStorage.getCorpId(), msgAuditSecret);

      try {
        HttpGet httpGet = new HttpGet(url);
        if (this.httpProxy != null) {
          RequestConfig config = RequestConfig.custom()
            .setProxy(this.httpProxy).build();
          httpGet.setConfig(config);
        }
        String resultContent = getRequestHttpClient().execute(httpGet, ApacheBasicResponseHandler.INSTANCE);
        WxError error = WxError.fromJson(resultContent, WxType.CP);
        if (error.getErrorCode() != 0) {
          throw new WxErrorException(error);
        }

        WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);

View on GitHub (pinned to 1c43293a3c)

Solutions

  1. Set the msg-audit secret via configStorage.setMsgAuditSecret("your-msg-audit-secret") during initialization
  2. In Spring Boot starter, set wx.cp.msg-audit-secret in application.yml
  3. Confirm the 会话存档 feature is enabled in the WeChat Work admin console and copy the exact secret
  4. Ensure all corp configs in a multi-tenant setup include the msgAudit secret if they use archive features

Example fix

// before
WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
config.setCorpId("corp123");
config.setCorpSecret("app-secret");
// msgAuditSecret not set → getMsgAuditAccessToken fails

// after
config.setMsgAuditSecret(System.getenv("WX_CP_MSG_AUDIT_SECRET"));
config.setMsgAuditPriKey(System.getenv("WX_CP_MSG_AUDIT_PRI_KEY")); // also needed for decryption
Defensive patterns

Strategy: validation

Validate before calling

// Validate msg-audit secret at startup
String msgAuditSecret = configStorage.getMsgAuditSecret();
if (StringUtils.isBlank(msgAuditSecret)) {
  throw new IllegalStateException("启动检查失败:会话存档 secret 未配置");
}
String priKey = configStorage.getMsgAuditPriKey();
if (StringUtils.isBlank(priKey)) {
  throw new IllegalStateException("启动检查失败:会话存档私钥 msgAuditPriKey 未配置");
}

Prevention

When it happens

Trigger: Calling any msg-audit method that needs an access_token (getChatRecords, getMediaFile, etc.) via the Apache HttpClient service when configStorage.getMsgAuditSecret() returns null or blank.

Common situations: The config storage was initialized without setMsgAuditSecret(); the 会话存档 feature was not enabled in the WeChat Work admin console so the secret was never obtained; the secret env var is missing in production; using a multi-config (multi-corp) setup where one config object lacks the msgAudit secret.

Related errors


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