{"record":{"id":"ed42902f0454e912","repo":"justauth/JustAuth","slug":"accesstokenobject-get-msg","errorCode":null,"errorMessage":"accessTokenObject.get(\"msg\")","messagePattern":"accessTokenObject\\.get\\(\"msg\"\\)","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthQqRequest.java","lineNumber":118,"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())\n            .queryParam(\"access_token\", authToken.getAccessToken())\n            .queryParam(\"oauth_consumer_key\", config.getClientId())\n            .queryParam(\"openid\", authToken.getOpenId())\n            .build();\n    }\n\n    private AuthToken getAuthToken(String response) {\n        Map<String, String> accessTokenObject = GlobalAuthUtils.parseStringToMap(response);\n        if (!accessTokenObject.containsKey(\"access_token\") || accessTokenObject.containsKey(\"code\")) {\n            throw new AuthException(accessTokenObject.get(\"msg\"));\n        }\n        return AuthToken.builder()\n            .accessToken(accessTokenObject.get(\"access_token\"))\n            .expireIn(Integer.parseInt(accessTokenObject.getOrDefault(\"expires_in\", \"0\")))\n            .refreshToken(accessTokenObject.get(\"refresh_token\"))\n            .build();\n    }\n\n    @Override\n    public String authorize(String state) {\n        return UrlBuilder.fromBaseUrl(super.authorize(state))\n            .queryParam(\"scope\", this.getScopes(\",\", false, AuthScopeUtils.getDefaultScopes(AuthQqScope.values())))\n            .build();\n    }\n}\n","sourceCodeStart":100,"sourceCodeEnd":134,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java#L100-L134","documentation":"AuthQqRequest.getAuthToken throws AuthException with the 'msg' field when the token-endpoint response (parsed as a URL-encoded query string, not JSON) lacks access_token or contains a 'code' key. QQ signals grant failures via code/msg pairs in the query string.","triggerScenarios":"getAccessToken or refresh when QQ returns e.g. ?code=100005&msg=clientid非法 or code=100009 (redirect uri format illegal) instead of an access_token.","commonSituations":"Wrong clientid/clientsecret, redirect_uri not exactly matching the one registered in QQ Connect (must be the callback domain registered, down to path), or the PC-vs-WAP callback URL confusion for QQ interconnect.","solutions":["Decode the msg value (URL-encoded Chinese message) — it names the exact QQ error (e.g. clientid非法, redirect uri非法)","Ensure redirectUri in AuthConfig exactly equals the registered callback (QQ requires exact match)","Verify QQ Connect app审核 status: unapproved apps only work for the developer's own QQ number (code 100010 style errors)","Test login with the developer QQ account first if the app is pending review"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n    qqRequest.getAuthResponse(callback);\n} catch (AuthException e) {\n    // message is QQ's msg param; URL-decode it for the Chinese reason (e.g. redirect uri非法)\n    log.warn(\"QQ grant error: {}\", java.net.URLDecoder.decode(String.valueOf(e.getMessage()), java.nio.charset.StandardCharsets.UTF_8));\n}","preventionTips":["Match redirectUri exactly to the QQ Connect registered callback","During app review pending status, test only with the developer's QQ account","URL-decode msg before logging or displaying"],"tags":["oauth","qq","redirect-uri","app-review","auth-exception"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}