{"record":{"id":"0db8ea88348870d6","repo":"binarywang/WxJava","slug":"appid-0db8ea","errorCode":null,"errorMessage":"知识助理请求需要配置appid","messagePattern":"知识助理请求需要配置appid","errorType":"validation","errorClass":"WxErrorException","httpStatus":null,"severity":"error","filePath":"weixin-java-aispeech/src/main/java/me/chanjar/weixin/aispeech/api/impl/WxAispeechServiceImpl.java","lineNumber":184,"sourceCode":"    }\n    HttpEntity entity = builder.build();\n    request.setEntity(entity);\n    if (entity.getContentType() != null) {\n      request.setHeader(\"Content-Type\", entity.getContentType());\n    }\n    enrichKnowledgeHeaders(request, \"\");\n    return executeRequest(request);\n  }\n\n  protected String executeKnowledgeDelete(String path) throws WxErrorException {\n    HttpUriRequestBase request = new HttpUriRequestBase(\"DELETE\", URI.create(configStorage.getKnowledgeApiBaseUrl() + path));\n    enrichKnowledgeHeaders(request, \"\");\n    return executeRequest(request);\n  }\n\n  private void enrichKnowledgeHeaders(HttpUriRequestBase request, String body) throws WxErrorException {\n    if (StringUtils.isBlank(configStorage.getAppid())) {\n      throw new WxErrorException(\"知识助理请求需要配置appid\");\n    }\n    if (StringUtils.isBlank(configStorage.getSecretKey())) {\n      throw new WxErrorException(\"知识助理请求需要配置secretKey\");\n    }\n\n    String requestId = UUID.randomUUID().toString();\n    long timestamp = System.currentTimeMillis() / 1000;\n    String nonce = randomNonce();\n    String signature = WxAispeechSignUtil.calcKnowledgeSignature(configStorage.getSecretKey(), timestamp, nonce,\n      requestId, body);\n\n    request.setHeader(\"X-APPID\", configStorage.getAppid());\n    request.setHeader(\"X-Request-ID\", requestId);\n    request.setHeader(\"X-Timestamp\", String.valueOf(timestamp));\n    request.setHeader(\"X-Nonce\", nonce);\n    request.setHeader(\"X-Signature\", signature);\n    if (!request.containsHeader(\"Content-Type\")) {\n      request.setHeader(\"Content-Type\", ContentType.APPLICATION_JSON.getMimeType());","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-aispeech/src/main/java/me/chanjar/weixin/aispeech/api/impl/WxAispeechServiceImpl.java#L166-L202","documentation":"Thrown by `enrichKnowledgeHeaders` before any Knowledge-assistant request (GET/POST/PUT/DELETE/multipart) when `configStorage.appid` is blank. The Knowledge API signs requests with appid+secretKey, so appid is mandatory. It is a WxErrorException thrown before the HTTP call is made.","triggerScenarios":"Calling any knowledge-assistant operation (list/create/update/delete/upload) without having configured appid on the AI Speech config storage.","commonSituations":"Only dialog credentials were set up; appid property omitted from config; env var for appid unresolved.","solutions":["Set appid on the config storage: `configStorage.setAppid(...)`.","Confirm both appid AND secretKey are configured (secretKey is checked immediately after).","Add a startup assertion that knowledge credentials are present if knowledge features are used."],"exampleFix":"// before\nservice.executeKnowledgeGet(\"/knowledge/list\", null);  // throws\n// after\nconfigStorage.setAppid(\"your-appid\");\nconfigStorage.setSecretKey(\"your-secret\");\nservice.executeKnowledgeGet(\"/knowledge/list\", null);","handlingStrategy":"validation","validationCode":"// Guard knowledge calls: require appid (and secretKey)\nif (StringUtils.isBlank(configStorage.getAppid())) {\n    throw new IllegalStateException(\"Knowledge API requires appid to be configured\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure both appid and secretKey before using knowledge features.","Validate at startup that knowledge credentials are set if knowledge is enabled.","Keep dialog-only and knowledge credentials distinct and documented."],"tags":["aispeech","knowledge","config","runtime"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}