{"record":{"id":"5c1449c63a376805","repo":"binarywang/WxJava","slug":"secret","errorCode":null,"errorMessage":"微信开放平台 secret 不能为空","messagePattern":"微信开放平台 secret 不能为空","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/AbstractWxOpenConfiguration.java","lineNumber":101,"sourceCode":"    }\n    wxOpenService.setWxOpenConfigStorage(configStorage);\n    return wxOpenService;\n  }\n\n  private void configApp(WxOpenInMemoryConfigStorage config, WxOpenSingleProperties appProperties) {\n    String appId = appProperties.getAppId();\n    String secret = appProperties.getSecret();\n    String token = appProperties.getToken();\n    String aesKey = appProperties.getAesKey();\n    String apiHostUrl = appProperties.getApiHostUrl();\n    String accessTokenUrl = appProperties.getAccessTokenUrl();\n\n    // appId 和 secret 是必需的\n    if (StringUtils.isBlank(appId)) {\n      throw new IllegalArgumentException(\"微信开放平台 appId 不能为空\");\n    }\n    if (StringUtils.isBlank(secret)) {\n      throw new IllegalArgumentException(\"微信开放平台 secret 不能为空\");\n    }\n\n    config.setComponentAppId(appId);\n    config.setComponentAppSecret(secret);\n    if (StringUtils.isNotBlank(token)) {\n      config.setComponentToken(token);\n    }\n    if (StringUtils.isNotBlank(aesKey)) {\n      config.setComponentAesKey(aesKey);\n    }\n    // 设置URL配置\n    config.setApiHostUrl(StringUtils.trimToNull(apiHostUrl));\n    config.setAccessTokenUrl(StringUtils.trimToNull(accessTokenUrl));\n  }\n\n  private void configHttp(WxOpenInMemoryConfigStorage config, WxOpenMultiProperties.ConfigStorage storage) {\n    String httpProxyHost = storage.getHttpProxyHost();\n    Integer httpProxyPort = storage.getHttpProxyPort();","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/configuration/services/AbstractWxOpenConfiguration.java#L83-L119","documentation":"Thrown by `configApp` in the Spring Boot multi-account Open Platform starter when a tenant's `secret` (componentAppSecret) is blank. The component secret is required to exchange for component tokens. It is an IllegalArgumentException thrown right after the appId check.","triggerScenarios":"An entry under `wx.open.apps` whose `secret` is missing/blank/whitespace, regardless of whether appId is set.","commonSituations":"Secret omitted in YAML; secret sourced from an env var that is not exported in the runtime environment; secret redacted before deploy.","solutions":["Provide a non-blank `secret` for the tenant.","If using env vars, ensure the variable is present in the deployment environment.","Restart; the check passes once StringUtils.isBlank(secret) is false."],"exampleFix":"# before\nwx.open.apps:\n  tenant-a: { appId: wxopen001 }   # secret missing -> throws\n# after\nwx.open.apps:\n  tenant-a: { appId: wxopen001, secret: ${WXOPEN_SECRET} }","handlingStrategy":"validation","validationCode":"// Open multi: assert secret present per tenant\nfor (WxOpenSingleProperties p : appsMap.values()) {\n    if (StringUtils.isBlank(p.getSecret())) {\n        throw new IllegalArgumentException(\"Open platform secret is required for tenant \" + p.getAppId());\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never commit real secrets; supply via env/secrets manager.","Fail fast at startup if any secret resolves blank.","Rotate secrets and update both client config and server."],"tags":["config","open","spring-boot","validation","secret","startup"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}