{"record":{"id":"f3f81a3609d8eb38","repo":"justauth/JustAuth","slug":"errordescription","errorCode":null,"errorMessage":"errorDescription","messagePattern":"errorDescription","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java","lineNumber":79,"sourceCode":"            .rawUserInfo(object)\n            .uuid(object.getString(\"id\"))\n            .username(object.getString(\"login\"))\n            .avatar(object.getString(\"avatar_url\"))\n            .blog(object.getString(\"blog\"))\n            .nickname(object.getString(\"name\"))\n            .company(object.getString(\"company\"))\n            .location(object.getString(\"location\"))\n            .email(object.getString(\"email\"))\n            .remark(object.getString(\"bio\"))\n            .gender(AuthUserGender.UNKNOWN)\n            .token(authToken)\n            .source(source.toString())\n            .build();\n    }\n\n    private void checkResponse(boolean error, String errorDescription) {\n        if (error) {\n            throw new AuthException(errorDescription);\n        }\n    }\n\n    /**\n     * 返回带{@code state}参数的授权url，授权回调时会带上这个{@code state}\n     *\n     * @param state state 验证授权流程的参数，可以防止csrf\n     * @return 返回授权地址\n     */\n    @Override\n    public String authorize(String state) {\n        return UrlBuilder.fromBaseUrl(super.authorize(state))\n            .queryParam(\"scope\", this.getScopes(\" \", true, AuthScopeUtils.getDefaultScopes(AuthGithubScope.values())))\n            .build();\n    }\n\n}\n","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java#L61-L97","documentation":"AuthGithubRequest.checkResponse(boolean error, String errorDescription) is called with a flag derived from the response (presence of an 'error' key) and the error_description string; when the flag is true it throws AuthException with just that description. GitHub's OAuth failures return {error, error_description, error_uri}.","triggerScenarios":"Token exchange with a wrong client_secret or mismatched redirect_uri, or redeeming a code twice - GitHub responds with error='bad_verification_code' and the description becomes the exception message; also fires on the user endpoint for an expired token.","commonSituations":"The 10-minute validity window of the GitHub code expiring before exchange (slow handler, queue lag); client secret rotated by a GitHub App; redirect_uri http/https mismatch with the GitHub OAuth app settings.","solutions":["Exchange the code promptly (GitHub codes expire in ~10 minutes) and only once - reload of the callback page is the classic trigger for bad_verification_code.","Verify client_id/client_secret pair against the GitHub Developer settings OAuth Apps page.","Ensure redirect_uri matches exactly what is registered, including scheme and trailing slash.","For 'bad expiration' or token-invalid errors, refresh or re-authorize instead of retrying the same token."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    return githubRequest.getAccessToken(callback);\n} catch (AuthException e) {\n    String m = String.valueOf(e.getErrorMsg());\n    if (m.contains(\"bad_verification_code\")) {\n        return AuthResponse.builder().msg(\"GitHub code expired or already used - restart the login flow\").build();\n    }\n    throw e;\n}","preventionTips":["Exchange the GitHub code within its ~10-minute window - process callbacks synchronously, do not queue them.","Prevent double exchange: the authorize page's redirect should never be refreshable (use redirects, POST-then-redirect).","Keep the GitHub OAuth app's callback URL and secret in sync with deployed config."],"tags":["oauth","github","justauth","api-error","token-exchange"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}