{"record":{"id":"aafa52f45426aa28","repo":"dromara/Sa-Token","slug":"30126-aafa52","errorCode":"30126","errorMessage":"无效 grant_type: ","messagePattern":"无效 grant_type: ","errorType":"exception","errorClass":"SaOAuth2Exception","httpStatus":null,"severity":"error","filePath":"sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java","lineNumber":191,"sourceCode":"\t\tSaManager.getLog().info(\"自定义 GRANT_TYPE [{}] (处理器: {})\", handler.getHandlerGrantType(), handler.getClass().getCanonicalName());\n\t}\n\n\t/**\n\t * 移除一个 grant_type 处理器\n\t */\n\tpublic void removeGrantTypeHandler(String scope) {\n\t\tgrantTypeHandlerMap.remove(scope);\n\t}\n\n\t/**\n\t * 根据 grantType 构造一个 AccessTokenModel\n\t */\n\tpublic SaOAuth2GrantTypeAuthFunction grantTypeAuth = (req) -> {\n\t\t// 先校验提供的 grant_type 是否有效\n\t\tString grantType = req.getParamNotNull(SaOAuth2Consts.Param.grant_type);\n\t\tSaOAuth2GrantTypeHandlerInterface grantTypeHandler = grantTypeHandlerMap.get(grantType);\n\t\tif(grantTypeHandler == null) {\n\t\t\tthrow new SaOAuth2Exception(\"无效 grant_type: \" + grantType).setCode(SaOAuth2ErrorCode.CODE_30126);\n\t\t}\n\n\t\t// 针对 authorization_code 与 password 两种特殊 grant_type，需要判断全局是否开启\n\t\tSaOAuth2ServerConfig config = SaOAuth2Manager.getServerConfig();\n\t\tif(grantType.equals(GrantType.authorization_code) && !config.getEnableAuthorizationCode() ) {\n\t\t\tthrow new SaOAuth2Exception(\"系统未开放的 grant_type: \" + grantType).setCode(SaOAuth2ErrorCode.CODE_30126);\n\t\t}\n\t\tif(grantType.equals(GrantType.password) && !config.getEnablePassword() ) {\n\t\t\tthrow new SaOAuth2Exception(\"系统未开放的 grant_type: \" + grantType).setCode(SaOAuth2ErrorCode.CODE_30126);\n\t\t}\n\n\t\t// 校验 clientSecret 和 scope\n\t\tClientIdAndSecretModel clientIdAndSecretModel = SaOAuth2Manager.getDataResolver().readClientIdAndSecret(req);\n\t\tList<String> scopes = SaOAuth2Manager.getDataConverter().convertScopeStringToList(req.getParam(SaOAuth2Consts.Param.scope));\n\t\tSaClientModel clientModel = SaOAuth2Manager.getTemplate().checkClientSecretAndScope(clientIdAndSecretModel.getClientId(), clientIdAndSecretModel.getClientSecret(), scopes);\n\n\t\t// 检测应用是否开启此 grantType\n\t\tif(!clientModel.getAllowGrantTypes().contains(grantType)) {","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-plugin/sa-token-oauth2/src/main/java/cn/dev33/satoken/oauth2/strategy/SaOAuth2Strategy.java#L173-L209","documentation":"Thrown by SaOAuth2Strategy.grantTypeAuth: the grant_type parameter does not match any registered grant-type handler. Built-in handlers cover authorization_code and password (plus client_credentials on its own endpoint); anything unknown fails this lookup. Error code 30126.","triggerScenarios":"POST /oauth2/token with grant_type values such as 'refresh_token' when no such handler is registered, 'client_credentials' (handled on /oauth2/client_token, not here), typos, or a custom grant type whose handler was never added via addGrantTypeHandler.","commonSituations":"Developer expects standard OAuth2 refresh_token support out of the box; custom grant type defined but handler registration missing or keyed under a different string; version upgrade where a custom handler was registered on a different strategy instance.","solutions":["Use a supported grant_type: authorization_code or password on /oauth2/token (client_credentials goes to /oauth2/client_token)","For custom grant types, register the handler before use: SaOAuth2Strategy.instance.addGrantTypeHandler(\"my_grant\", handler)","Check for typos/whitespace in the grant_type parameter"],"exampleFix":"// before\n// custom grant type used but never registered\nPOST /oauth2/token  grant_type=my_grant\n\n// after\nSaOAuth2Strategy.instance.addGrantTypeHandler(\"my_grant\", new MyGrantTypeHandler());\nPOST /oauth2/token  grant_type=my_grant","handlingStrategy":"validation","validationCode":"Set<String> supported = new HashSet<>(Arrays.asList(\"authorization_code\", \"password\"));\n// plus any handler you registered via addGrantTypeHandler\nif(!supported.contains(grantType)) {\n    throw new IllegalArgumentException(\"unsupported grant_type: \" + grantType);\n}","typeGuard":null,"tryCatchPattern":"catch(SaOAuth2Exception e) { if(\"30126\".equals(e.getCode())) return badRequest(\"invalid grant_type: \" + e.getMessage()); }","preventionTips":["Register custom grant-type handlers in application init, before any request can arrive","Log registered handler keys at startup to catch missing registrations"],"tags":["oauth2","grant-type","extension","sa-token"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}