binarywang/WxJava · error · WxErrorException

知识助理请求需要配置secretKey

Error message

知识助理请求需要配置secretKey

What it means

Thrown by `enrichKnowledgeHeaders` immediately after the appid check when `configStorage.secretKey` is blank. The secretKey is used to compute the HMAC signature for Knowledge-assistant requests; without it the `X-Signature` cannot be produced. It is a WxErrorException.

Source

Thrown at weixin-java-aispeech/src/main/java/me/chanjar/weixin/aispeech/api/impl/WxAispeechServiceImpl.java:187

    if (entity.getContentType() != null) {
      request.setHeader("Content-Type", entity.getContentType());
    }
    enrichKnowledgeHeaders(request, "");
    return executeRequest(request);
  }

  protected String executeKnowledgeDelete(String path) throws WxErrorException {
    HttpUriRequestBase request = new HttpUriRequestBase("DELETE", URI.create(configStorage.getKnowledgeApiBaseUrl() + path));
    enrichKnowledgeHeaders(request, "");
    return executeRequest(request);
  }

  private void enrichKnowledgeHeaders(HttpUriRequestBase request, String body) throws WxErrorException {
    if (StringUtils.isBlank(configStorage.getAppid())) {
      throw new WxErrorException("知识助理请求需要配置appid");
    }
    if (StringUtils.isBlank(configStorage.getSecretKey())) {
      throw new WxErrorException("知识助理请求需要配置secretKey");
    }

    String requestId = UUID.randomUUID().toString();
    long timestamp = System.currentTimeMillis() / 1000;
    String nonce = randomNonce();
    String signature = WxAispeechSignUtil.calcKnowledgeSignature(configStorage.getSecretKey(), timestamp, nonce,
      requestId, body);

    request.setHeader("X-APPID", configStorage.getAppid());
    request.setHeader("X-Request-ID", requestId);
    request.setHeader("X-Timestamp", String.valueOf(timestamp));
    request.setHeader("X-Nonce", nonce);
    request.setHeader("X-Signature", signature);
    if (!request.containsHeader("Content-Type")) {
      request.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
    }
  }

View on GitHub (pinned to 1c43293a3c)

Solutions

  1. Set secretKey on the config storage: `configStorage.setSecretKey(...)`.
  2. Ensure the env var supplying the secret is present in the runtime environment.
  3. Restart/refresh after rotation.

Example fix

// before
configStorage.setAppid("your-appid");
service.executeKnowledgePost("/knowledge", body);  // throws
// after
configStorage.setAppid("your-appid");
configStorage.setSecretKey("${AISPEECH_SECRET}");
service.executeKnowledgePost("/knowledge", body);
Defensive patterns

Strategy: validation

Validate before calling

// Guard knowledge calls: require secretKey
if (StringUtils.isBlank(configStorage.getSecretKey())) {
    throw new IllegalStateException("Knowledge API requires secretKey to be configured");
}

Prevention

When it happens

Trigger: Any knowledge-assistant call when appid is set but secretKey is missing/blank.

Common situations: Secret omitted from config; secret env var not exported; secret rotated server-side but not updated in the client config.

Related errors


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