{"record":{"id":"21c9c248f454b4f0","repo":"justauth/JustAuth","slug":"error-description-21c9c2","errorCode":null,"errorMessage":"${error_description}","messagePattern":"\\$\\{error_description\\}","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java","lineNumber":56,"sourceCode":"    }\n\n    private AuthToken getAuthToken(JSONObject object) {\n        this.checkResponse(object);\n\n        return AuthToken.builder()\n            .accessToken(object.getString(\"access_token\"))\n            .expireIn(object.getIntValue(\"expires_in\"))\n            .tokenType(object.getString(\"token_type\"))\n            .idToken(object.getString(\"id_token\"))\n            .refreshToken(object.getString(\"refresh_token\"))\n            .uid(object.getString(\"taobao_user_id\"))\n            .openId(object.getString(\"taobao_open_uid\"))\n            .build();\n    }\n\n    private void checkResponse(JSONObject object) {\n        if (object.containsKey(\"error\")) {\n            throw new AuthException(object.getString(\"error_description\"));\n        }\n    }\n\n    @Override\n    public AuthUser getUserInfo(AuthToken authToken) {\n        String response = doPostAuthorizationCode(authToken.getAccessCode());\n        JSONObject accessTokenObject = JSONObject.parseObject(response);\n        if (accessTokenObject.containsKey(\"error\")) {\n            throw new AuthException(accessTokenObject.getString(\"error_description\"));\n        }\n        authToken = this.getAuthToken(accessTokenObject);\n\n        String nick = GlobalAuthUtils.urlDecode(accessTokenObject.getString(\"taobao_user_nick\"));\n        return AuthUser.builder()\n            .rawUserInfo(accessTokenObject)\n            .uuid(StringUtils.isEmpty(authToken.getUid()) ? authToken.getOpenId() : authToken.getUid())\n            .username(nick)\n            .nickname(nick)","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java#L38-L74","documentation":"In AuthTaobaoRequest.getUserInfo, the raw token-endpoint response is parsed and, if it contains an `error` key, JustAuth throws AuthException carrying the `error_description` field verbatim (no numeric code). Note the quirk of this provider class: getUserInfo internally re-runs the code exchange (doPostAuthorizationCode) rather than using the passed token, so this error fires during the login/userInfo step against taobao's token endpoint.","triggerScenarios":"Calling getUserInfo on AuthTaobaoRequest when the token response contains an error: invalid/expired/reused authorization code, wrong appkey/appsecret, or redirect_uri not whitelisted in the Taobao open platform console.","commonSituations":"Taobao open-platform app credentials rotated; callback hitting getUserInfo twice (code already consumed); sandbox vs production environment mismatch; ISV app not yet published/scoped for the required API.","solutions":["Read error_description: Taobao messages usually state the exact cause (e.g. 'invalid code', 'appkey not exist', 'redirect_uri mismatch').","Ensure the authorization code from the callback is used once and immediately — cache nothing across retries.","Verify app key/app secret and the callback URL registered in the Taobao open platform console match AuthConfig exactly.","Confirm your app has the required API scope granted (e.g. taobao.user.info) and is approved."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// validate callback shape before invoking Taobao flow\nif (StringUtils.isEmpty(callback.getCode())) {\n    throw new IllegalArgumentException(\"missing 'code' in Taobao callback\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    AuthUser u = taobaoRequest.getUserInfo(token);\n} catch (AuthException e) {\n    log.warn(\"Taobao token exchange failed: {}\", e.getMessage());\n    // re-send user to authorization instead of looping\n    redirect(taobaoRequest.authorize(newState()));\n}","preventionTips":["Ensure the Taobao code is single-use: guard the callback endpoint against duplicates.","Keep appkey/secret and the registered callback URL synchronized in config management.","Log error_description verbatim — Taobao includes precise causes."],"tags":["justauth","taobao","oauth","api-error","code-reuse"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}