{"record":{"id":"bf19841f82f0533a","repo":"alibaba/arthas","slug":"required-parameter-is-missing","errorCode":null,"errorMessage":"Required parameter '{}' is missing","messagePattern":"Required parameter '(.+?)' is missing","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/tool/DefaultToolCallback.java","lineNumber":110,"sourceCode":"    /**\n     * validate the required parameters\n     */\n    private void validateRequiredParameters(Map<String, Object> toolArguments) {\n        Parameter[] parameters = this.toolMethod.getParameters();\n        \n        for (Parameter parameter : parameters) {\n            if (parameter.getType().isAssignableFrom(ToolContext.class)) {\n                continue;\n            }\n            \n            ToolParam toolParam = parameter.getAnnotation(ToolParam.class);\n            if (toolParam != null && toolParam.required()) {\n                String paramName = parameter.getName();\n                Object paramValue = toolArguments.get(paramName);\n                \n                // check if the parameter is empty or an empty string\n                if (paramValue == null) {\n                    throw new IllegalArgumentException(\"Required parameter '\" + paramName + \"' is missing\");\n                }\n\n                if (paramValue instanceof String && ((String) paramValue).trim().isEmpty()) {\n                    throw new IllegalArgumentException(\"Required parameter '\" + paramName + \"' cannot be empty\");\n                }\n            }\n        }\n    }\n\n    private Map<String, Object> extractToolArguments(String toolInput) {\n        return JsonParser.fromJson(toolInput, new TypeReference<Map<String, Object>>() {\n        });\n    }\n\n    private Object[] buildMethodArguments(Map<String, Object> toolInputArguments, ToolContext toolContext) {\n        return Stream.of(this.toolMethod.getParameters()).map(parameter -> {\n            if (parameter.getType().isAssignableFrom(ToolContext.class)) {\n                return toolContext;","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/tool/DefaultToolCallback.java#L92-L128","documentation":"Thrown by DefaultToolCallback.validateRequiredParameters() when invoking a @Tool method whose parameter is annotated @ToolParam(required = true) and the corresponding argument is null (absent from the tool input). It is an IllegalArgumentException thrown synchronously during tool dispatch, before the method body runs. A separate guard rejects empty/blank strings with 'cannot be empty'.","triggerScenarios":"An MCP client calls the tool without supplying a parameter declared @ToolParam(required = true); the JSON arguments map lacks that key; the key name does not match the Java parameter name (e.g. -parameters compiler flag missing so parameter.getName() returns 'arg0').","commonSituations":"Client omitting a required field; parameter name mismatch due to compiling without the -parameters flag (so paramName becomes 'arg0' and never matches the client's key); schema/client drift on required fields.","solutions":["Ensure the MCP client sends all parameters marked @ToolParam(required = true) with non-null values.","Compile with the -parameters javac flag so parameter names resolve correctly and match the argument keys.","Mark the parameter optional (required = false) if it is genuinely optional, or supply a default in the method.","Align the tool's input JSON schema with the @ToolParam annotations so clients know required fields."],"exampleFix":"// before\npublic String run(@ToolParam(required = true) String path) { ... }\n// compiled without -parameters -> paramName == \"arg0\", client sends \"path\"\n\n// after (javac)\n<plugin>\n  <artifactId>maven-compiler-plugin</artifactId>\n  <configuration><parameters>true</parameters></configuration>\n</plugin>\n// and ensure the client includes {\"path\": \"/some/value\"}","handlingStrategy":"validation","validationCode":"// Client-side: ensure all required @ToolParam fields are present and non-null\nMap<String,Object> args = new HashMap<>();\nargs.put(\"path\", Objects.requireNonNull(path));\n// verify no required key is null before invoking the tool\nfor (String req : requiredParams) {\n    if (args.get(req) == null) throw new IllegalArgumentException(\"missing \" + req);\n}","typeGuard":"// Guard that a required argument is a non-blank string\nstatic boolean isPresentString(Map<String,Object> args, String key) {\n    Object v = args.get(key);\n    return v != null && (!(v instanceof String s) || !s.trim().isEmpty());\n}","tryCatchPattern":"try {\n    toolCallback.call(toolInput);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"is missing\") || e.getMessage().contains(\"cannot be empty\")) {\n        // report the missing/empty required param back to the client\n        return errorResponse(e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Compile with -parameters so @ToolParam names resolve to real names (not arg0).","Send every parameter marked @ToolParam(required = true) as non-null.","Keep the tool's JSON input schema in sync with the annotations.","Mark genuinely optional parameters required = false."],"tags":["mcp","tool","validation","toolparam","java"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}