{"record":{"id":"c4a7d5fbc3d59621","repo":"apache/shardingsphere","slug":"s-must-be-an-integer","errorCode":null,"errorMessage":"%s must be an integer.","messagePattern":"(.+?) must be an integer\\.","errorType":"validation","errorClass":"MCPInvalidRequestException","httpStatus":null,"severity":"error","filePath":"mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/request/MCPToolArguments.java","lineNumber":128,"sourceCode":"        int result = parseIntegerArgument(name, value, defaultValue);\n        if (result < minValue || result > maxValue) {\n            throw new MCPInvalidRequestException(String.format(\"%s must be an integer between %d and %d.\", name, minValue, maxValue));\n        }\n        return result;\n    }\n    \n    private int parseIntegerArgument(final String name, final Object value, final int defaultValue) {\n        if (null == value) {\n            return defaultValue;\n        }\n        String actualValue = Objects.toString(value, \"\").trim();\n        if (actualValue.isEmpty()) {\n            return defaultValue;\n        }\n        try {\n            return Integer.parseInt(actualValue);\n        } catch (final NumberFormatException ex) {\n            throw new MCPInvalidRequestException(String.format(\"%s must be an integer.\", name), ex);\n        }\n    }\n    \n    /**\n     * Get string collection argument.\n     *\n     * @param name argument name\n     * @return string collection\n     */\n    public List<String> getStringCollectionArgument(final String name) {\n        Object rawValue = arguments.get(name);\n        if (!(rawValue instanceof Collection)) {\n            return Collections.emptyList();\n        }\n        List<String> result = new LinkedList<>();\n        for (Object each : (Collection<?>) rawValue) {\n            String actualValue = Objects.toString(each, \"\").trim();\n            if (!actualValue.isEmpty()) {","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/request/MCPToolArguments.java#L110-L146","documentation":"Thrown by MCPToolArguments.parseIntegerArgument when an MCP tool argument that must be an integer is present and non-empty but Integer.parseInt fails. Null and blank values silently fall back to the default value; only a present, non-blank, non-parsable value throws MCPInvalidRequestException. This is the MCP layer's argument validation, not a database error.","triggerScenarios":"Calling an MCP tool whose descriptor declares an integer argument (via getIntegerArgument) with a value like \"abc\", \"10.5\", true, or an object whose toString() is not a base-10 integer string. JSON floats such as 3.5 or numbers in scientific notation also fail because Integer.parseInt rejects them.","commonSituations":"An LLM client serializing numbers as strings (\"100\"), sending a float where an int is expected, passing a boolean, or embedding units/whitespace in a numeric field; also schema drift when a tool argument type changes between versions.","solutions":["Send the argument as a plain JSON integer or an integer string (e.g. 30 or \"30\") with no decimal point, spaces, or units.","Omit the argument entirely (or send null) to accept the tool's documented default instead of sending a malformed value.","If you control the caller, validate/coerce the value with a parse-int check before invoking the tool.","On the server side, extend the tool description/schema with an explicit integer type hint so LLM clients do not improvise string formats."],"exampleFix":"// before\ntoolArguments.put(\"max_rows\", \"30 rows\");\n// after\ntoolArguments.put(\"max_rows\", 30);","handlingStrategy":"validation","validationCode":"Object v = arguments.get(\"max_rows\");\nif (null != v && !(v instanceof Integer) && !v.toString().trim().matches(\"-?\\\\d+\")) {\n    throw new IllegalArgumentException(\"max_rows must be an integer, got: \" + v);\n}","typeGuard":"const isIntArg = v => v == null || Number.isInteger(v) || /^-?\\d+$/.test(String(v).trim());","tryCatchPattern":"try {\n    int rows = args.getIntegerArgument(\"max_rows\", 50);\n} catch (final MCPInvalidRequestException ex) {\n    // surface ex.getMessage() to the tool caller and re-ask with a corrected integer value\n}","preventionTips":["Declare integer arguments as type integer (not string/number) in tool JSON schemas","Coerce or reject non-integer values client-side before the tool call","Omit optional numeric arguments instead of sending empty strings"],"tags":["mcp","validation","arguments","integer-parsing"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}