binarywang/WxJava · error · RuntimeException

请确保企业微信配置唯一性[{corpId}]

Error message

请确保企业微信配置唯一性[{corpId}]

What it means

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.

Source

Thrown at spring-boot-starters/wx-java-cp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/configuration/services/AbstractWxCpConfiguration.java:67

     * <p>但同一 corpId 下不允许出现重复的 agentId(包括多个 null)。</p>
     *
     * 查看 {@link me.chanjar.weixin.cp.config.impl.AbstractWxCpInRedisConfigImpl#setAgentId(Integer)}
     */
    Collection<WxCpSingleProperties> corpList = corps.values();
    if (corpList.size() > 1) {
      // 先按 corpId 分组统计
      Map<String, List<WxCpSingleProperties>> corpsMap = corpList.stream()
        .collect(Collectors.groupingBy(WxCpSingleProperties::getCorpId));
      Set<Map.Entry<String, List<WxCpSingleProperties>>> entries = corpsMap.entrySet();
      for (Map.Entry<String, List<WxCpSingleProperties>> entry : entries) {
        String corpId = entry.getKey();
        // 校验每个企业下,agentId 是否唯一
        boolean multi = entry.getValue().stream()
          // 通讯录没有 agentId,使用字符串转换避免 null 与 agentId=0 冲突
          .collect(Collectors.groupingBy(c -> Objects.toString(c.getAgentId(), "null"), Collectors.counting()))
          .entrySet().stream().anyMatch(e -> e.getValue() > 1);
        if (multi) {
          throw new RuntimeException("请确保企业微信配置唯一性[" + corpId + "]");
        }
      }
    }
    WxCpMultiServicesImpl services = new WxCpMultiServicesImpl();

    Set<Map.Entry<String, WxCpSingleProperties>> entries = corps.entrySet();
    for (Map.Entry<String, WxCpSingleProperties> entry : entries) {
      String tenantId = entry.getKey();
      WxCpSingleProperties wxCpSingleProperties = entry.getValue();
      WxCpDefaultConfigImpl storage = this.wxCpConfigStorage(wxCpMultiProperties);
      this.configCorp(storage, wxCpSingleProperties);
      this.configHttp(storage, wxCpMultiProperties.getConfigStorage());
      WxCpService wxCpService = this.wxCpService(storage, wxCpMultiProperties.getConfigStorage());
      services.addWxCpService(tenantId, wxCpService);
    }
    return services;
  }

View on GitHub (pinned to 1c43293a3c)

Solutions

  1. Use the corpId in the message to locate the corp section.
  2. Assign a distinct `agentId` to each app under that corp.
  3. Avoid two null-agentId apps under the same corp; split across corps/instances if needed.

Example fix

# before
wx.cp.apps:
  a: { corpId: ww corp, agentId: 1000002 }
  b: { corpId: ww corp, agentId: 1000002 }
# after
wx.cp.apps:
  a: { corpId: ww corp, agentId: 1000002 }
  b: { corpId: ww corp, agentId: 1000008 }
Defensive patterns

Strategy: validation

Validate before calling

// Spring Boot CP multi: pre-flight corpId+agentId uniqueness
for (List<WxCpSingleProperties> corps : corpList.stream()
        .collect(Collectors.groupingBy(WxCpSingleProperties::getCorpId)).values()) {
    Set<String> seen = new HashSet<>();
    for (WxCpSingleProperties p : corps) {
        if (!seen.add(Objects.toString(p.getAgentId(), "null"))) {
            throw new IllegalStateException("Duplicate agentId under corp " + p.getCorpId());
        }
    }
}

Prevention

When it happens

Trigger: Two apps with identical `corpId` AND identical `agentId`; or two contacts-type apps (agentId null) for the same corp.

Common situations: Cloning an app config block and reusing its agentId; configuring duplicate contacts apps for one enterprise.

Related errors


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