{"record":{"id":"fea40627fbff6639","repo":"justauth/JustAuth","slug":"error-description-error-description","errorCode":null,"errorMessage":"${error_description} ${error_description}","messagePattern":"\\$\\{error_description\\} \\$\\{error_description\\}","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthAmazonRequest.java","lineNumber":133,"sourceCode":"        String response = new HttpUtils(config.getHttpConfig()).post(url, param, httpHeader, false).getBody();\n        JSONObject jsonObject = JSONObject.parseObject(response);\n        this.checkResponse(jsonObject);\n        return AuthToken.builder()\n            .accessToken(jsonObject.getString(\"access_token\"))\n            .tokenType(jsonObject.getString(\"token_type\"))\n            .expireIn(jsonObject.getIntValue(\"expires_in\"))\n            .refreshToken(jsonObject.getString(\"refresh_token\"))\n            .build();\n    }\n\n    /**\n     * 校验响应内容是否正确\n     *\n     * @param jsonObject 响应内容\n     */\n    private void checkResponse(JSONObject jsonObject) {\n        if (jsonObject.containsKey(\"error\")) {\n            throw new AuthException(jsonObject.getString(\"error_description\").concat(\" \") + jsonObject.getString(\"error_description\"));\n        }\n    }\n\n    /**\n     * https://developer.amazon.com/zh/docs/login-with-amazon/obtain-customer-profile.html#call-profile-endpoint\n     *\n     * @param authToken token信息\n     * @return AuthUser\n     */\n    @Override\n    public AuthUser getUserInfo(AuthToken authToken) {\n        String accessToken = authToken.getAccessToken();\n        this.checkToken(accessToken);\n\n        HttpHeader httpHeader = new HttpHeader();\n        httpHeader.add(\"Host\", \"api.amazon.com\");\n        httpHeader.add(\"Authorization\", \"bearer \" + accessToken);\n        String userInfo = new HttpUtils(config.getHttpConfig()).get(this.source.userInfo(), new HashMap<>(0), httpHeader, false).getBody();","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthAmazonRequest.java#L115-L151","documentation":"Thrown by AuthAmazonRequest.checkResponse when the token-endpoint JSON contains an 'error' key. The message concatenates error_description with itself — a copy-paste bug: the first term should have been jsonObject.getString(\"error\") (the error code). Expect the human-readable description twice instead of 'code: description'.","triggerScenarios":"Any Amazon token or refresh call whose response body includes an error field: invalid_client (bad client id/secret), invalid_grant (bad/expired code or redirect_uri mismatch), invalid_scope, authorization_pending in the LWA device flow.","commonSituations":"Client secret rotated on the Amazon dev console but not in AuthConfig; auth code replayed (single-use, ~10 min lifetime); redirect URI not matching the one registered in the Login with Amazon security profile.","solutions":["Read the (duplicated) description text — it names the actual error even though the code is missing due to the bug","Verify clientId/clientSecret against the Amazon developer console security profile","Ensure redirectUri exactly matches the allowed return URLs of the security profile","Exchange the authorization grant promptly; grant_type=authorization_code grants are single-use"],"exampleFix":"// before (library code, AuthAmazonRequest.checkResponse)\nthrow new AuthException(jsonObject.getString(\"error_description\").concat(\" \") + jsonObject.getString(\"error_description\"));\n\n// after (fixed upstream)\nthrow new AuthException(jsonObject.getString(\"error\").concat(\" \") + jsonObject.getString(\"error_description\"));\n\n// workaround for callers: match on the description substring, e.g. catch (AuthException e) { if (e.getMessage().contains(\"invalid_client\")) ... }","handlingStrategy":"try-catch","validationCode":"if (StringUtils.isEmpty(config.getClientSecret())) {\n    throw new IllegalStateException(\"AMAZON clientSecret required\");\n}\nif (!redirectUriRegisteredExactly(config.getRedirectUri())) {\n    throw new IllegalStateException(\"redirect uri must match the LWA security profile exactly\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return amazonRequest.getAccessToken(callback);\n} catch (AuthException e) {\n    String m = e.getMessage(); // note: description duplicated, code lost (library bug)\n    if (m.contains(\"invalid_client\")) refreshCredentialsFromConsole();\n    else if (m.contains(\"invalid_grant\")) return redirectToAuthorize(AMAZON);\n    throw e;\n}","preventionTips":["Register the exact return URL in the Login with Amazon security profile","Rotate client secrets on both console and config together","Never reuse Amazon auth grants — they are single-use"],"tags":["amazon","oauth","bug","token-endpoint"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}