{"record":{"id":"fe5113ebfddbdc59","repo":"justauth/JustAuth","slug":"errmsg-fe5113","errorCode":null,"errorMessage":"${errmsg}","messagePattern":"\\$\\{errmsg\\}","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AbstractAuthWeChatEnterpriseRequest.java","lineNumber":86,"sourceCode":"            .email(userDetail.getString(\"email\"))\n            .uuid(userId)\n            .gender(AuthUserGender.getWechatRealGender(userDetail.getString(\"gender\")))\n            .token(authToken)\n            .source(source.toString())\n            .build();\n    }\n\n    /**\n     * 校验请求结果\n     *\n     * @param response 请求结果\n     * @return 如果请求结果正常，则返回JSONObject\n     */\n    private JSONObject checkResponse(String response) {\n        JSONObject object = JSONObject.parseObject(response);\n\n        if (object.containsKey(\"errcode\") && object.getIntValue(\"errcode\") != 0) {\n            throw new AuthException(object.getString(\"errmsg\"), source);\n        }\n\n        return object;\n    }\n\n\n    /**\n     * 返回获取accessToken的url\n     *\n     * @param code 授权码\n     * @return 返回获取accessToken的url\n     */\n    @Override\n    protected String accessTokenUrl(String code) {\n        return UrlBuilder.fromBaseUrl(source.accessToken())\n            .queryParam(\"corpid\", config.getClientId())\n            .queryParam(\"corpsecret\", config.getClientSecret())\n            .build();","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AbstractAuthWeChatEnterpriseRequest.java#L68-L104","documentation":"AbstractAuthWeChatEnterpriseRequest.checkResponse parses every WeChat Work (企业微信) API response and, when errcode is present and non-zero, throws AuthException carrying WeChat's errmsg (with the source attached). This is the pass-through of WeChat Work's native error envelope, covering token, user-info, and user-detail calls.","triggerScenarios":"Expired or invalid access_token (errcode 40014/42001) when calling getAccessToken/getUserInfo; wrong corpId/secret producing 40001 invalid credential; invalid code (40029) from a mismatched agentId or reused code; API calls where the IP is not in the trusted list (60020).","commonSituations":"Access tokens cached too long and used after their 7200s expiry; secret rotated in the WeChat Work admin console but not in AuthConfig; server IP not whitelisted under the app's IP trust configuration; agentId from a different app than the secret.","solutions":["Log the numeric errcode with the message — WeChat Work's error-code reference pinpoints the exact cause (40014/42001 = token expired, 40029 = bad code, 60020 = IP not trusted).","Ensure corpId, agentId (secret's app) and secret in AuthConfig come from the same self-built app, and the callback code was issued to that app.","Add the server egress IP to the app's trusted IP list in the WeChat Work admin console.","For token-expiry errors, re-run getAccessToken before retrying the user-info call once."],"exampleFix":"// before\n// token cached indefinitely; after 2h WeChat returns errcode 42001 -> errmsg exception\n\n// after\ntry { return request.getUserInfo(token); }\ncatch (AuthException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"42001\")) {\n        AuthToken fresh = request.getAccessToken(callback); // then retry once\n        return request.getUserInfo(fresh);\n    }\n    throw e;\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return request.getUserInfo(token); } catch (AuthException e) { String m = String.valueOf(e.getMessage()); if (m.contains(\"42001\") || m.contains(\"40014\")) { AuthToken fresh = request.getAccessToken(callback); return request.getUserInfo(fresh); } throw e; }","preventionTips":["Cache WeChat Work access tokens with their 7200s expiry and refresh proactively.","Keep corpId/agentId/secret from one app in sync in config.","Whitelist the server egress IP in the WeChat Work admin console.","Always log the numeric errcode alongside errmsg."],"tags":["justauth","wechat-work","api-error","token-expiry","external-api"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}