binarywang/WxJava · error · IllegalArgumentException
uri参数中不允许有access_token: {uri}
Error message
uri参数中不允许有access_token: {uri} What it means
The Channel service's executeInternal refuses any URI that already contains the substring 'access_token='. The library is responsible for fetching and appending the access_token itself (line 234), so a caller-supplied token would be duplicated or stale and would leak the token into logs. This is a hard precondition enforced before any network call.
Source
Thrown at weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java:225
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
}
} else {
throw e;
}
}
} while (retryTimes++ < this.maxRetryTimes);
log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
throw new WxRuntimeException("微信服务端异常,超出重试次数");
}
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefreshToken,
boolean printResult) throws WxErrorException {
E dataForLog = DataUtils.handleDataWithSecret(data);
if (uri.contains("access_token=")) {
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
}
String accessToken = getAccessToken(false);
WxChannelConfig config = this.getConfig();
if (StringUtils.isNotEmpty(config.getApiHostUrl())) {
uri = uri.replace("https://api.weixin.qq.com", config.getApiHostUrl());
}
String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken;
try {
T result = executor.execute(uriWithAccessToken, data, WxType.Channel);
log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog,
printResult ? result : "...");
return result;
} catch (WxErrorException e) {
WxError error = e.getError();
if (WxConsts.ACCESS_TOKEN_ERROR_CODES.contains(error.getErrorCode())) {View on GitHub (pinned to 1c43293a3c)
Solutions
- Pass only the path-and-query portion of the endpoint (e.g. /channel/eclyle/...), never including access_token.
- If you have a full URL, strip the access_token query parameter before handing it to the service.
- Audit any URI-building helpers to ensure they never append access_token; the SDK owns token injection.
Example fix
// before — caller appended token String url = "https://api.weixin.qq.com/cgi-bin/...?access_token=" + token; service.executeGet(url); // after — pass clean path, SDK appends token String url = "https://api.weixin.qq.com/cgi-bin/..."; service.executeGet(url);
Defensive patterns
Strategy: validation
Validate before calling
if (uri != null && uri.contains("access_token=")) {
// strip any existing access_token param — the SDK appends its own
uri = uri.replaceAll("([?&])access_token=[^&]*", "$1").replaceAll("[?&]$", "");
}
// now safe to pass to channelService Try / catch
try {
service.executeGet(uri);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("access_token")) {
// strip and retry, or fix the URI source
}
throw e;
} Prevention
- Never hand a fully-formed WeChat URL with a token to the service; pass bare paths.
- Centralise URL building in one helper that never appends access_token.
- Add a unit test asserting URIs passed to execute* never contain 'access_token='.
When it happens
Trigger: A caller passes a pre-built or cached URL that already includes '?access_token=...' (or '&access_token=...') into any WxChannelService execute/media/upload method.
Common situations: Copy-pasting a fully-formed WeChat endpoint URL from docs or a captured request; reusing a URL object that had the token appended by a previous call; building URIs with a helper that auto-adds the token.
Related errors
- 表单字段名不能为空
- setAttribute: name parameter cannot be null
- 非法请求参数,有部分参数为空 :
- uri参数中不允许有access_token: {}
- 更新「联系我」方式需要指定configId
AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14).
Data as JSON: /api/errors/92f2712c0a43446a.
Report an issue: GitHub.