binarywang/WxJava · error · IllegalArgumentException

uri参数中不允许有access_token:

Error message

uri参数中不允许有access_token: 

What it means

Thrown as IllegalArgumentException when executeInternal detects that the caller-supplied URI already contains 'access_token=' as a query parameter. The MiniApp library injects the access token automatically after the URI; pre-embedding the token is treated as a programming error.

Source

Thrown at weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java:430

          } catch (InterruptedException e1) {
            Thread.currentThread().interrupt();
          }
        } else {
          throw e;
        }
      }
    } while (retryTimes++ < this.maxRetryTimes);

    log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
    throw new WxRuntimeException("微信服务端异常,超出重试次数");
  }

  private <R, T> R executeInternal(
      ExecutorAction<R> executor, String uri, String dataForLog, boolean doNotAutoRefreshToken)
      throws WxErrorException {

    if (uri.contains("access_token=")) {
      throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
    }
    String accessToken = getAccessToken(false);

    String effectiveApiHostUrl = this.getWxMaConfig().getEffectiveApiHostUrl();
    if (!WxMaConfig.DEFAULT_API_HOST_URL.equals(effectiveApiHostUrl)) {
      uri = uri.replace(WxMaConfig.DEFAULT_API_HOST_URL, effectiveApiHostUrl);
    }

    String uriWithAccessToken =
        uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken;
    try {
      R result = executor.execute(uriWithAccessToken);
      log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
      return result;
    } catch (WxErrorException e) {
      WxError error = e.getError();
      if (WxConsts.ACCESS_TOKEN_ERROR_CODES.contains(error.getErrorCode())) {
        // 强制设置WxMaConfig的access token过期了,这样在下一次请求里就会刷新access token

View on GitHub (pinned to 1c43293a3c)

Solutions

  1. Remove 'access_token=...' from the URI string before passing it to the service method
  2. Pass only the base API path and non-token query parameters; the library appends the token automatically
  3. If building URLs dynamically, strip any existing access_token parameter before calling

Example fix

// before
service.get("https://api.weixin.qq.com/cgi-bin/draft/get?access_token=TOKEN", null);

// after
service.get("https://api.weixin.qq.com/cgi-bin/draft/get", null);
Defensive patterns

Strategy: validation

Validate before calling

// Validate URI before calling the service
if (uri != null && uri.contains("access_token=")) {
  throw new IllegalArgumentException("URI must not contain access_token; the library injects it automatically");
}
service.get(uri, null);

Type guard

private static boolean isUriSafe(String uri) {
  return uri != null && !uri.contains("access_token=");
}

Try / catch

try {
  service.get(uri, null);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("access_token")) {
    uri = uri.replaceAll("[?&]access_token=[^&]*", "");
    service.get(uri, null);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Caller passes a URI string containing 'access_token=xxx' to any MiniApp service method routed through executeInternal, e.g., service.get('https://api.weixin.qq.com/...?access_token=TOKEN&foo=bar', null).

Common situations: Copy-paste from WeChat API documentation sample URLs that include the token parameter; manually building URLs with the token included; debugging code left in production.

Related errors


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