{"record":{"id":"81034d7fe1c96be0","repo":"alibaba/spring-ai-alibaba","slug":"tool-params-invalid","errorCode":"TOOL_PARAMS_INVALID","errorMessage":"TOOL_PARAMS_INVALID: authorization_position (position must be header or query)","messagePattern":"TOOL_PARAMS_INVALID: authorization_position \\(position must be header or query\\)","errorType":"error_code","errorClass":"BizException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/service/impl/ToolExecutionServiceImpl.java","lineNumber":146,"sourceCode":"\t\t\t// populate auth info to either header or query\n\t\t\tif (pluginConfig.getAuth() != null && pluginConfig.getAuth().getType() != Plugin.ApiAuthType.NONE) {\n\t\t\t\tPlugin.ApiAuth auth = pluginConfig.getAuth();\n\t\t\t\tPlugin.AuthorizationType authType = auth.getAuthorizationType();\n\t\t\t\tif (authType == Plugin.AuthorizationType.BEARER) {\n\t\t\t\t\theaders.put(HttpHeaders.AUTHORIZATION, \"Bearer \" + auth.getAuthorizationValue());\n\t\t\t\t}\n\t\t\t\telse if (authType == Plugin.AuthorizationType.BASIC) {\n\t\t\t\t\theaders.put(HttpHeaders.AUTHORIZATION, \"Basic \" + auth.getAuthorizationValue());\n\t\t\t\t}\n\t\t\t\telse if (authType == Plugin.AuthorizationType.CUSTOM) {\n\t\t\t\t\tif (auth.getAuthorizationPosition() == Plugin.AuthorizationPosition.HEADER) {\n\t\t\t\t\t\theaders.put(auth.getAuthorizationKey(), auth.getAuthorizationValue());\n\t\t\t\t\t}\n\t\t\t\t\telse if (auth.getAuthorizationPosition() == Plugin.AuthorizationPosition.QUERY) {\n\t\t\t\t\t\tqueryParameters.put(auth.getAuthorizationKey(), auth.getAuthorizationValue());\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthrow new BizException(ErrorCode.TOOL_PARAMS_INVALID.toError(\"authorization_position\",\n\t\t\t\t\t\t\t\t\"position must be header or query\"));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthrow new BizException(ErrorCode.TOOL_PARAMS_INVALID.toError(\"authorization_type\",\n\t\t\t\t\t\t\t\"type must be basic, bearer or custom\"));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// populate input params to header, path, query or body\n\t\t\tList<ApiParameter> apiParameters = toolConfig.getInputParams();\n\t\t\tMap<String, Object> paramValues = request.getArguments();\n\t\t\tfor (ApiParameter apiParameter : apiParameters) {\n\t\t\t\tApiParameterLocation location = ApiParameterLocation\n\t\t\t\t\t.of(StringUtils.lowerCase(apiParameter.getLocation()));\n\t\t\t\tif (location == null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/service/impl/ToolExecutionServiceImpl.java#L128-L164","documentation":"TOOL_PARAMS_INVALID with parameter 'authorization_position' is thrown by ToolExecutionServiceImpl.callOpenApi when a plugin's authorization is configured with a Plugin.AuthorizationPosition value that is neither HEADER nor QUERY. Only those two positions are supported for placing credentials on the outgoing HTTP request.","triggerScenarios":"A plugin's auth configuration persisted an unknown/legacy AuthorizationPosition enum value; deserialization produced a value outside the handled enum set; the config JSON contains a position string that maps to no supported case.","commonSituations":"Manually editing plugin config in the database and entering an invalid position; version upgrade where an old enum constant is no longer handled; importing a plugin export from another version with a different enum set.","solutions":["Set the plugin's authorization position to 'header' or 'query' in the plugin configuration UI.","Inspect the stored plugin JSON and fix the authorizationPosition field to a supported value.","Re-create the plugin with valid auth config if the stored enum is corrupt.","If you need another position (e.g. cookie), it is unsupported — migrate auth to header/query."],"exampleFix":"// before (plugin config JSON)\n{\"authorization\": {\"type\": \"bearer\", \"position\": \"cookie\"}}\n// after\n{\"authorization\": {\"type\": \"bearer\", \"position\": \"header\"}}","handlingStrategy":"validation","validationCode":"Plugin.AuthorizationPosition pos = plugin.getAuthorization().getAuthorizationPosition();\nif (pos != Plugin.AuthorizationPosition.HEADER && pos != Plugin.AuthorizationPosition.QUERY) {\n    throw new IllegalArgumentException(\"authorization position must be header or query\");\n}","typeGuard":"boolean hasValidAuthPosition(Plugin p) {\n    Plugin.AuthorizationPosition pos = p.getAuthorization().getAuthorizationPosition();\n    return pos == Plugin.AuthorizationPosition.HEADER || pos == Plugin.AuthorizationPosition.QUERY;\n}","tryCatchPattern":"try {\n    toolExecutionService.executeTool(request);\n} catch (BizException e) {\n    if (e.getMessage().contains(\"authorization_position\")) {\n        // fix the plugin auth config and re-run\n    }\n    throw e;\n}","preventionTips":["Restrict the auth-position field in the plugin editor to header/query options only.","Validate plugin auth config on save so invalid positions never persist.","After version upgrades, re-validate stored plugin auth configs against the current enum.","Avoid hand-editing plugin config JSON in the database."],"tags":["validation","authorization","openapi","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}