apache/shardingsphere · error · MCPInvalidToolArgumentException
%s must be an integer between %d and %d.
Error message
%s must be an integer between %d and %d.
What it means
SQLExecutionToolHandlerSupport.getIntegerArgument catches the MCPInvalidRequestException raised by MCPToolArguments.getIntegerArgument for numeric arguments (e.g. max_rows) and rethrows MCPInvalidToolArgumentException: '%s must be an integer between %d and %d.' with the tool name, minimum, and maximum. Bounds for max_rows are 0..MCPRuntimeProtectionPolicy.MAX_ROWS_LIMIT (0 meaning 'use the default'). This validates numeric tool arguments before any SQL is analyzed or executed.
Source
Thrown at mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/SQLExecutionToolHandlerSupport.java:102
if (database.isEmpty()) {
return "";
}
List<ShardingSphereSchema> schemas = requestContext.getMetadataQueryFacade().querySchemas(database);
return 1 == schemas.size() ? schemas.iterator().next().getName() : "";
}
private static int resolveMaxRows(final MCPToolArguments toolArguments, final String sourceTool) {
int result = getIntegerArgument(toolArguments, sourceTool, "max_rows", MCPRuntimeProtectionPolicy.DEFAULT_MAX_ROWS, 0, MCPRuntimeProtectionPolicy.MAX_ROWS_LIMIT,
MCPRuntimeProtectionPolicy.DEFAULT_MAX_ROWS);
return 0 == result ? MCPRuntimeProtectionPolicy.DEFAULT_MAX_ROWS : result;
}
private static int getIntegerArgument(final MCPToolArguments toolArguments, final String sourceTool, final String argumentPath, final int defaultValue, final int minimumValue,
final int maximumValue, final int suggestedValue) {
try {
return toolArguments.getIntegerArgument(argumentPath, defaultValue, minimumValue, maximumValue);
} catch (final MCPInvalidRequestException ex) {
throw new MCPInvalidToolArgumentException(sourceTool, sourceTool, argumentPath, minimumValue, maximumValue, suggestedValue, ex);
}
}
static void putIfNotEmpty(final Map<String, Object> target, final String key, final String value) {
if (!value.isEmpty()) {
target.put(key, value);
}
}
}
View on GitHub (pinned to e952770a21)
Solutions
- Send max_rows as an integer within [0, MAX_ROWS_LIMIT], or omit it to get the default.
- Coerce and clamp client-side before invoking the tool.
- If a higher limit is truly needed, have the operator raise MCPRuntimeProtectionPolicy.MAX_ROWS_LIMIT.
Example fix
// before
await tools.call('database_gateway_execute_query', { sql, max_rows: 'all' }); // not an integer -> error
// after
await tools.call('database_gateway_execute_query', { sql, max_rows: 200 }); Defensive patterns
Strategy: validation
Validate before calling
function normalizeMaxRows(raw) {
const n = Number(raw);
if (!Number.isInteger(n) || n < 0 || n > MAX_ROWS_LIMIT) {
return DEFAULT_MAX_ROWS; // omit to use server default, or throw early with a clear message
}
return n;
}
const args = { sql };
const maxRows = normalizeMaxRows(userMaxRows);
if (maxRows !== DEFAULT_MAX_ROWS) args.max_rows = maxRows; Type guard
function isValidMaxRows(value) {
return Number.isInteger(value) && value >= 0 && value <= MAX_ROWS_LIMIT;
} Try / catch
try {
return await tools.call('database_gateway_execute_query', { sql, max_rows });
} catch (e) {
if (/must be an integer between/.test(e.message)) {
const [, min, max] = e.message.match(/between (\d+) and (\d+)/) ?? [];
return tools.call('database_gateway_execute_query', { sql, max_rows: Math.min(Math.max(0, max_rows|0), Number(max)) });
}
throw e;
} Prevention
- Coerce numeric tool arguments to integers client-side; never send strings.
- Clamp max_rows into [0, limit] or omit it for the default.
- Parse the min/max from the error message to self-correct once.
- Learn the deployed MAX_ROWS_LIMIT before promising large result pages.
When it happens
Trigger: Passing max_rows (or another numeric argument) as a non-integer (string like 'all', float), an integer below the minimum, or above the configured MAX_ROWS_LIMIT.
Common situations: LLM emitting "max_rows": "100" as a string or "max_rows": 1000000 exceeding the cap; UI default of -1; JSON coercion surprises where numbers arrive as strings.
Related errors
- Completion argument `%s` is not declared for %s `%s`.
- %s execution_mode is required.
- %s execution_mode must be one of %s.
- database_gateway_execute_query only supports parser-approved
- database_gateway_execute_update does not accept read-only SQ
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/577c4172e01ca491.
Report an issue: GitHub.