{"record":{"id":"57981c040867d372","repo":"justauth/JustAuth","slug":"object-containskey-error-object-getstri","errorCode":null,"errorMessage":"object.containsKey(\"error\") + \":\" + object.getString(\"error_description\")","messagePattern":"object\\.containsKey\\(\"error\"\\) \\+ \":\" \\+ object\\.getString\\(\"error_description\"\\)","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java","lineNumber":104,"sourceCode":"    /**\n     * 返回获取userInfo的url\n     *\n     * @param authToken 用户授权后的token\n     * @return 返回获取userInfo的url\n     */\n    @Override\n    protected String userInfoUrl(AuthToken authToken) {\n        return UrlBuilder.fromBaseUrl(source.userInfo()).queryParam(\"access_token\", authToken.getAccessToken()).build();\n    }\n\n    /**\n     * 检查响应内容是否正确\n     *\n     * @param object 请求响应内容\n     */\n    private void checkResponse(JSONObject object) {\n        if (object.containsKey(\"error\") || object.containsKey(\"error_description\")) {\n            throw new AuthException(object.containsKey(\"error\") + \":\" + object.getString(\"error_description\"));\n        }\n    }\n}\n","sourceCodeStart":86,"sourceCodeEnd":108,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java#L86-L108","documentation":"AuthGoogleRequest.checkResponse() throws when a Google response carries 'error' or 'error_description'. Note a formatting quirk in the message: it concatenates the boolean containsKey(\"error\") with the description, so typical output is 'true:...' (or 'false:<description>' when only error_description is present) - the useful text is whatever follows the colon.","triggerScenarios":"Token exchange with a mismatched client_secret or redirect_uri (Google returns error='invalid_grant'/'invalid_client'), a code exchanged twice, or userinfo called with a revoked/expired Google token.","commonSituations":"Google Cloud OAuth client secret rotated; redirect URI not added to the Google Cloud Console authorized redirect URIs (exact match required, no trailing slash); clock skew on the server causing 'invalid_grant' on code exchange; user revoked third-party access in their Google account.","solutions":["Verify the client_id/client_secret pair and that AuthConfig.redirectUri appears verbatim in Google Cloud Console > Credentials > Authorized redirect URIs.","Sync server time (NTP) - Google rejects token requests with significant clock drift.","Parse the text after ':' in the exception message for the actual Google error string ('invalid_grant', 'redirect_uri_mismatch', etc.).","Re-authorize the user when the error is revoked/invalid token; refreshing will not help for revoked grants."],"exampleFix":"// before - boolean leaks into the message\nif (object.containsKey(\"error\") || object.containsKey(\"error_description\")) {\n    throw new AuthException(object.containsKey(\"error\") + \":\" + object.getString(\"error_description\"));\n}\n\n// after - emit the real error text\nif (object.containsKey(\"error\") || object.containsKey(\"error_description\")) {\n    String err = object.getString(\"error\");\n    String desc = object.getString(\"error_description\");\n    throw new AuthException(err != null ? err + \":\" + desc : desc);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    return googleRequest.getAccessToken(callback);\n} catch (AuthException e) {\n    // message looks like 'true:<google description>' - use the part after the colon\n    String desc = String.valueOf(e.getErrorMsg()).replaceFirst(\"^(true|false):\", \"\");\n    if (desc.contains(\"invalid_client\")) {\n        throw new ConfigurationException(\"Google client credentials rejected\", e);\n    }\n    if (desc.contains(\"redirect_uri_mismatch\")) {\n        throw new ConfigurationException(\"Add the exact redirectUri in Google Cloud Console\", e);\n    }\n    throw e;\n}","preventionTips":["Add the exact redirect URI (no trailing slash) to Google Cloud Console > Credentials before first login test.","Run NTP on servers - clock drift causes Google 'invalid_grant' during code exchange.","Do not trust the raw exception message format for Google - parse after the leading boolean prefix."],"tags":["oauth","google","justauth","api-error","error-message-format"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}