binarywang/WxJava · error · IllegalArgumentException
uri参数中不允许有access_token: {}
Error message
uri参数中不允许有access_token: {} What it means
Thrown by BaseCpServiceImpl.executeInternal() when the supplied uri already contains the substring 'access_token='. The service appends access_token itself after fetching it from config storage, so a caller-provided token is treated as a misuse/leak risk and rejected with IllegalArgumentException before the request is sent.
Source
Thrown at weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java:394
}
/**
* Execute internal t.
*
* @param <T> the type parameter
* @param <E> the type parameter
* @param executor the executor
* @param uri the uri
* @param data the data
* @param doNotAutoRefresh the do not auto refresh
* @return the t
* @throws WxErrorException the wx error exception
*/
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefresh) throws WxErrorException {
E dataForLog = DataUtils.handleDataWithSecret(data);
if (uri.contains("access_token=")) {
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
}
String accessToken = getAccessToken(false);
String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken;
try {
T result = executor.execute(uriWithAccessToken, data, WxType.CP);
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())) {
// 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
this.configStorage.expireAccessToken();
if (this.getWxCpConfigStorage().autoRefreshToken() && !doNotAutoRefresh) {
log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
//下一次不再自动重试View on GitHub (pinned to 1c43293a3c)
Solutions
- Pass the bare endpoint URL without access_token; the service injects it from config storage.
- If using executeNormal with a pre-built URL, strip the access_token query param first.
- Avoid logging or caching full URLs that include tokens.
Example fix
// before String url = "https://qyapi.weixin.qq.com/cgi-bin/...?access_token=" + token; service.get(url, null); // after String url = "https://qyapi.weixin.qq.com/cgi-bin/..."; service.get(url, null); // token added by the service
Defensive patterns
Strategy: validation
Validate before calling
if (uri != null && uri.contains("access_token=")) {
throw new IllegalArgumentException("uri must not include access_token; service injects it");
}
service.get(uri, null); Type guard
static boolean uriHasToken(String uri) { return uri != null && uri.contains("access_token="); } Try / catch
null
Prevention
- Pass bare endpoint URLs; let the service append the token.
- Never cache/log full URLs containing tokens.
- Strip access_token before calling executeNormal with pre-built URLs.
When it happens
Trigger: A caller manually appends access_token to the URL (e.g. from a cached token), or passes a full WeChat URL that already includes the query parameter, or builds the URI from a template that pre-fills access_token.
Common situations: Copy-pasting a full WeChat API URL with token into the uri argument; migrating from a hand-rolled client that put the token in the URL; debugging code that hardcoded a token.
Related errors
- 缺少agentid参数
- 「联系我」使用人数默认限制不超过100人(包括部门展开后的人数)
- uri参数中不允许有access_token: {uri}
- 微信服务端异常,超出重试次数
- 请确保企业微信配置唯一性[{corpId}]
AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14).
Data as JSON: /api/errors/05551c07e8cca41f.
Report an issue: GitHub.