{"record":{"id":"d3c9bc4dbee988cd","repo":"binarywang/WxJava","slug":"corpid-d3c9bc","errorCode":null,"errorMessage":"请确保企业微信配置唯一性[{corpId}]","messagePattern":"请确保企业微信配置唯一性\\[(.+?)\\]","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-boot-starters/wx-java-cp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/configuration/services/AbstractWxCpConfiguration.java","lineNumber":67,"sourceCode":"     * <p>但同一 corpId 下不允许出现重复的 agentId（包括多个 null）。</p>\n     *\n     * 查看 {@link me.chanjar.weixin.cp.config.impl.AbstractWxCpInRedisConfigImpl#setAgentId(Integer)}\n     */\n    Collection<WxCpSingleProperties> corpList = corps.values();\n    if (corpList.size() > 1) {\n      // 先按 corpId 分组统计\n      Map<String, List<WxCpSingleProperties>> corpsMap = corpList.stream()\n        .collect(Collectors.groupingBy(WxCpSingleProperties::getCorpId));\n      Set<Map.Entry<String, List<WxCpSingleProperties>>> entries = corpsMap.entrySet();\n      for (Map.Entry<String, List<WxCpSingleProperties>> entry : entries) {\n        String corpId = entry.getKey();\n        // 校验每个企业下，agentId 是否唯一\n        boolean multi = entry.getValue().stream()\n          // 通讯录没有 agentId，使用字符串转换避免 null 与 agentId=0 冲突\n          .collect(Collectors.groupingBy(c -> Objects.toString(c.getAgentId(), \"null\"), Collectors.counting()))\n          .entrySet().stream().anyMatch(e -> e.getValue() > 1);\n        if (multi) {\n          throw new RuntimeException(\"请确保企业微信配置唯一性[\" + corpId + \"]\");\n        }\n      }\n    }\n    WxCpMultiServicesImpl services = new WxCpMultiServicesImpl();\n\n    Set<Map.Entry<String, WxCpSingleProperties>> entries = corps.entrySet();\n    for (Map.Entry<String, WxCpSingleProperties> entry : entries) {\n      String tenantId = entry.getKey();\n      WxCpSingleProperties wxCpSingleProperties = entry.getValue();\n      WxCpDefaultConfigImpl storage = this.wxCpConfigStorage(wxCpMultiProperties);\n      this.configCorp(storage, wxCpSingleProperties);\n      this.configHttp(storage, wxCpMultiProperties.getConfigStorage());\n      WxCpService wxCpService = this.wxCpService(storage, wxCpMultiProperties.getConfigStorage());\n      services.addWxCpService(tenantId, wxCpService);\n    }\n    return services;\n  }\n","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/spring-boot-starters/wx-java-cp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/configuration/services/AbstractWxCpConfiguration.java#L49-L85","documentation":"Thrown by the Spring Boot multi-account WeChat Work (企业微信) starter. Apps are grouped by `corpId`, and within each corp every `agentId` must be unique (otherwise token caches keyed by corpId+agentId collide). The offending corpId is embedded in the message. null agentId (contacts-sync apps) maps to \"null\" and two such entries under one corp also collide.","triggerScenarios":"Two apps with identical `corpId` AND identical `agentId`; or two contacts-type apps (agentId null) for the same corp.","commonSituations":"Cloning an app config block and reusing its agentId; configuring duplicate contacts apps for one enterprise.","solutions":["Use the corpId in the message to locate the corp section.","Assign a distinct `agentId` to each app under that corp.","Avoid two null-agentId apps under the same corp; split across corps/instances if needed."],"exampleFix":"# before\nwx.cp.apps:\n  a: { corpId: ww corp, agentId: 1000002 }\n  b: { corpId: ww corp, agentId: 1000002 }\n# after\nwx.cp.apps:\n  a: { corpId: ww corp, agentId: 1000002 }\n  b: { corpId: ww corp, agentId: 1000008 }","handlingStrategy":"validation","validationCode":"// Spring Boot CP multi: pre-flight corpId+agentId uniqueness\nfor (List<WxCpSingleProperties> corps : corpList.stream()\n        .collect(Collectors.groupingBy(WxCpSingleProperties::getCorpId)).values()) {\n    Set<String> seen = new HashSet<>();\n    for (WxCpSingleProperties p : corps) {\n        if (!seen.add(Objects.toString(p.getAgentId(), \"null\"))) {\n            throw new IllegalStateException(\"Duplicate agentId under corp \" + p.getCorpId());\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One agentId per corp per app.","At most one null-agentId (contacts) app per corp.","Document the corpId/agentId matrix alongside config."],"tags":["config","multi-tenant","wecom","cp","spring-boot","startup"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}