{"record":{"id":"70713ab314e846d8","repo":"xpipe-io/xpipe","slug":"missing-argument-for-key-key","errorCode":null,"errorMessage":"Missing argument for key \" + key","messagePattern":"Missing argument for key \" \\+ key","errorType":"exception","errorClass":"BeaconClientException","httpStatus":400,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/beacon/mcp/McpToolHandler.java","lineNumber":85,"sourceCode":"            return request;\n        }\n\n        public Optional<String> getOptionalStringArgument(String key) {\n            var o = request.arguments().get(key);\n            if (o == null) {\n                return Optional.empty();\n            }\n\n            if (!(o instanceof String s) || s.isBlank()) {\n                return Optional.empty();\n            }\n\n            return Optional.of(s);\n        }\n\n        public String getStringArgument(String key) throws BeaconClientException {\n            if (request.arguments() == null) {\n                throw new BeaconClientException(\"Missing argument for key \" + key);\n            }\n\n            var o = request.arguments().get(key);\n            if (o == null) {\n                throw new BeaconClientException(\"Missing argument for key \" + key);\n            }\n\n            if (!(o instanceof String s) || s.isBlank()) {\n                throw new BeaconClientException(\"Invalid argument for key \" + key);\n            }\n\n            return s;\n        }\n\n        public Optional<Boolean> getOptionalBooleanArgument(String key) {\n            var o = request.arguments().get(key);\n            if (o == null) {\n                return Optional.empty();","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/beacon/mcp/McpToolHandler.java#L67-L103","documentation":"McpToolHandler.getStringArgument requires a string-typed tool argument under the given key. When the MCP tool call request carries no arguments map at all (arguments() == null), no value can be retrieved, so it throws BeaconClientException.","triggerScenarios":"An MCP client invoking a tool without sending any 'arguments' object while the tool handler calls getStringArgument for a required parameter.","commonSituations":"Client omits the arguments object entirely for a no-thought invocation; hand-crafted JSON-RPC calls missing 'arguments'; older MCP clients not sending optional fields.","solutions":["Include the required key in the tool call's arguments object","Use getOptionalStringArgument for optional parameters","Client-side: validate required tool input against the tool's inputSchema before invoking","Return the tool's input schema requirement in the tool description so clients send it"],"exampleFix":"// before\nhandler.getStringArgument(\"connection\"); // arguments == null\n// after\nvar conn = handler.getOptionalStringArgument(\"connection\").orElseThrow(\n    () -> new IllegalArgumentException(\"'connection' is required\"));","handlingStrategy":"validation","validationCode":"if (toolCall.arguments() == null || toolCall.arguments().get(\"connection\") == null) {\n    throw new IllegalArgumentException(\"'connection' argument required\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    String v = handler.getStringArgument(key);\n} catch (BeaconClientException ex) {\n    if (ex.getMessage().contains(\"Missing argument\")) {\n        // reply to the MCP client with an input-schema error\n    } else throw ex;\n}","preventionTips":["Declare required properties with required[] in the tool's inputSchema","Use optional getters for non-mandatory params","Send an explicit arguments object even if mostly empty"],"tags":["mcp","arguments","xpipe"],"backgroundTag":"missing-required-argument","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}