apache/shardingsphere · error · MCPInvalidRequestException

%s must be an integer.

Error message

%s must be an integer.

What it means

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.

Source

Thrown at mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/request/MCPToolArguments.java:128

        int result = parseIntegerArgument(name, value, defaultValue);
        if (result < minValue || result > maxValue) {
            throw new MCPInvalidRequestException(String.format("%s must be an integer between %d and %d.", name, minValue, maxValue));
        }
        return result;
    }
    
    private int parseIntegerArgument(final String name, final Object value, final int defaultValue) {
        if (null == value) {
            return defaultValue;
        }
        String actualValue = Objects.toString(value, "").trim();
        if (actualValue.isEmpty()) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(actualValue);
        } catch (final NumberFormatException ex) {
            throw new MCPInvalidRequestException(String.format("%s must be an integer.", name), ex);
        }
    }
    
    /**
     * Get string collection argument.
     *
     * @param name argument name
     * @return string collection
     */
    public List<String> getStringCollectionArgument(final String name) {
        Object rawValue = arguments.get(name);
        if (!(rawValue instanceof Collection)) {
            return Collections.emptyList();
        }
        List<String> result = new LinkedList<>();
        for (Object each : (Collection<?>) rawValue) {
            String actualValue = Objects.toString(each, "").trim();
            if (!actualValue.isEmpty()) {

View on GitHub (pinned to e952770a21)

Solutions

  1. Send the argument as a plain JSON integer or an integer string (e.g. 30 or "30") with no decimal point, spaces, or units.
  2. Omit the argument entirely (or send null) to accept the tool's documented default instead of sending a malformed value.
  3. If you control the caller, validate/coerce the value with a parse-int check before invoking the tool.
  4. On the server side, extend the tool description/schema with an explicit integer type hint so LLM clients do not improvise string formats.

Example fix

// before
toolArguments.put("max_rows", "30 rows");
// after
toolArguments.put("max_rows", 30);
Defensive patterns

Strategy: validation

Validate before calling

Object v = arguments.get("max_rows");
if (null != v && !(v instanceof Integer) && !v.toString().trim().matches("-?\\d+")) {
    throw new IllegalArgumentException("max_rows must be an integer, got: " + v);
}

Type guard

const isIntArg = v => v == null || Number.isInteger(v) || /^-?\d+$/.test(String(v).trim());

Try / catch

try {
    int rows = args.getIntegerArgument("max_rows", 50);
} catch (final MCPInvalidRequestException ex) {
    // surface ex.getMessage() to the tool caller and re-ask with a corrected integer value
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/c4a7d5fbc3d59621. Report an issue: GitHub.