{"record":{"id":"92f2712c0a43446a","repo":"binarywang/WxJava","slug":"uri-access-token-uri","errorCode":null,"errorMessage":"uri参数中不允许有access_token: {uri}","messagePattern":"uri参数中不允许有access_token: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java","lineNumber":225,"sourceCode":"          } catch (InterruptedException e1) {\n            Thread.currentThread().interrupt();\n          }\n        } else {\n          throw e;\n        }\n      }\n    } while (retryTimes++ < this.maxRetryTimes);\n\n    log.warn(\"重试达到最大次数【{}】\", this.maxRetryTimes);\n    throw new WxRuntimeException(\"微信服务端异常，超出重试次数\");\n  }\n\n  protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefreshToken,\n                                     boolean printResult) throws WxErrorException {\n    E dataForLog = DataUtils.handleDataWithSecret(data);\n\n    if (uri.contains(\"access_token=\")) {\n      throw new IllegalArgumentException(\"uri参数中不允许有access_token: \" + uri);\n    }\n    String accessToken = getAccessToken(false);\n\n    WxChannelConfig config = this.getConfig();\n    if (StringUtils.isNotEmpty(config.getApiHostUrl())) {\n      uri = uri.replace(\"https://api.weixin.qq.com\", config.getApiHostUrl());\n    }\n\n    String uriWithAccessToken = uri + (uri.contains(\"?\") ? \"&\" : \"?\") + \"access_token=\" + accessToken;\n\n    try {\n      T result = executor.execute(uriWithAccessToken, data, WxType.Channel);\n      log.debug(\"\\n【请求地址】: {}\\n【请求参数】：{}\\n【响应数据】：{}\", uriWithAccessToken, dataForLog,\n        printResult ? result : \"...\");\n      return result;\n    } catch (WxErrorException e) {\n      WxError error = e.getError();\n      if (WxConsts.ACCESS_TOKEN_ERROR_CODES.contains(error.getErrorCode())) {","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java#L207-L243","documentation":"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.","triggerScenarios":"A caller passes a pre-built or cached URL that already includes '?access_token=...' (or '&access_token=...') into any WxChannelService execute/media/upload method.","commonSituations":"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.","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."],"exampleFix":"// before — caller appended token\nString url = \"https://api.weixin.qq.com/cgi-bin/...?access_token=\" + token;\nservice.executeGet(url);\n\n// after — pass clean path, SDK appends token\nString url = \"https://api.weixin.qq.com/cgi-bin/...\";\nservice.executeGet(url);","handlingStrategy":"validation","validationCode":"if (uri != null && uri.contains(\"access_token=\")) {\n  // strip any existing access_token param — the SDK appends its own\n  uri = uri.replaceAll(\"([?&])access_token=[^&]*\", \"$1\").replaceAll(\"[?&]$\", \"\");\n}\n// now safe to pass to channelService","typeGuard":null,"tryCatchPattern":"try {\n  service.executeGet(uri);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"access_token\")) {\n    // strip and retry, or fix the URI source\n  }\n  throw e;\n}","preventionTips":["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='."],"tags":["validation","access-token","channel","precondition"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}