binarywang/WxJava · error · RuntimeException

请确保微信视频号配置 appId 的唯一性

Error message

请确保微信视频号配置 appId 的唯一性

What it means

Thrown by the Solon multi-account Channel (视频号) auto-configuration when two or more tenant entries resolve to the same appId. Uniqueness is enforced because a shared Redis token/ticket cache is keyed by appId, so duplicate appIds would cause tokens to overwrite each other and cross-tenant leakage. It is a plain RuntimeException, so it fails application startup / bean wiring.

Source

Thrown at solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/configuration/services/AbstractWxChannelConfiguration.java:51

    Map<String, WxChannelSingleProperties> appsMap = wxChannelMultiProperties.getApps();
    if (appsMap == null || appsMap.isEmpty()) {
      log.warn("微信视频号应用参数未配置,通过 WxChannelMultiServices#getWxChannelService(\"tenantId\")获取实例将返回空");
      return new WxChannelMultiServicesImpl();
    }
    /**
     * 校验 appId 是否唯一,避免使用 redis 缓存 token、ticket 时错乱。
     *
     * 查看 {@link me.chanjar.weixin.channel.config.impl.WxChannelRedisConfigImpl#setAppid(String)}
     */
    Collection<WxChannelSingleProperties> apps = appsMap.values();
    if (apps.size() > 1) {
      // 校验 appId 是否唯一
      boolean multi = apps.stream()
        // 没有 appId,如果不判断是否为空,这里会报 NPE 异常
        .collect(Collectors.groupingBy(c -> c.getAppId() == null ? 0 : c.getAppId(), Collectors.counting()))
        .entrySet().stream().anyMatch(e -> e.getValue() > 1);
      if (multi) {
        throw new RuntimeException("请确保微信视频号配置 appId 的唯一性");
      }
    }
    WxChannelMultiServicesImpl services = new WxChannelMultiServicesImpl();

    Set<Map.Entry<String, WxChannelSingleProperties>> entries = appsMap.entrySet();
    for (Map.Entry<String, WxChannelSingleProperties> entry : entries) {
      String tenantId = entry.getKey();
      WxChannelSingleProperties wxChannelSingleProperties = entry.getValue();
      WxChannelDefaultConfigImpl storage = this.wxChannelConfigStorage(wxChannelMultiProperties);
      this.configApp(storage, wxChannelSingleProperties);
      this.configHttp(storage, wxChannelMultiProperties.getConfigStorage());
      WxChannelService wxChannelService = this.wxChannelService(storage, wxChannelMultiProperties);
      services.addWxChannelService(tenantId, wxChannelService);
    }
    return services;
  }

  /**

View on GitHub (pinned to 1c43293a3c)

Solutions

  1. Inspect every entry under `wxjava.channel.apps.*` and make each `appId` distinct.
  2. Ensure no two tenants share the same real appId; if you genuinely need the same appId twice, you must run separate application instances or separate Redis namespaces.
  3. Remove or fill in any entry with a blank/null appId.
  4. Re-run startup; the exception is gone once the groupingBy check finds no count > 1.

Example fix

// before
wxjava:
  channel:
    apps:
      tenant-a:
        appId: wx123
      tenant-b:
        appId: wx123   # duplicate -> throws
// after
wxjava:
  channel:
    apps:
      tenant-a:
        appId: wx123
      tenant-b:
        appId: wx456   # distinct
Defensive patterns

Strategy: validation

Validate before calling

// Run during startup, before the multi-service bean is built
Collection<WxChannelSingleProperties> apps = appsMap.values();
Map<Object, Long> counts = apps.stream()
    .collect(Collectors.groupingBy(
        c -> c.getAppId() == null ? "<null>" : c.getAppId(),
        Collectors.counting()));
List<Object> dupes = counts.entrySet().stream()
    .filter(e -> e.getValue() > 1)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());
if (!dupes.isEmpty()) {
    throw new IllegalStateException("Duplicate channel appIds: " + dupes);
}

Prevention

When it happens

Trigger: Configuring wx-java-channel-multi-solon-plugin with a `apps` map whose values contain two entries with the same `appId`. Also triggered when two entries both leave `appId` null, because null is collapsed to the literal key `0` and thus also counts as a duplicate.

Common situations: Copying a tenant block in YAML and forgetting to change appId; multi-tenant setups sharing one appId across environments; copy-paste of a config snippet where appId was templated out.

Related errors


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