{"record":{"id":"2f913323e171d64c","repo":"apache/shardingsphere","slug":"system-property-s-must-be-a-positive-integer-b","errorCode":null,"errorMessage":"System property `%s` must be a positive integer, but was `%s`.","messagePattern":"System property `(.+?)` must be a positive integer, but was `(.+?)`\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/security/MCPRuntimeProtectionPolicy.java","lineNumber":77,"sourceCode":"    /**\n     * Get maximum completion requests per minute for one MCP session.\n     *\n     * @return maximum completion requests per minute\n     */\n    public static int getMaxCompletionRequestsPerMinute() {\n        return getPositiveIntegerProperty(MAX_COMPLETION_REQUESTS_PER_MINUTE_PROPERTY, DEFAULT_MAX_COMPLETION_REQUESTS_PER_MINUTE);\n    }\n    \n    private static int getPositiveIntegerProperty(final String propertyName, final int defaultValue) {\n        String configuredValue = System.getProperty(propertyName);\n        if (null == configuredValue) {\n            return defaultValue;\n        }\n        int result;\n        try {\n            result = Integer.parseInt(configuredValue);\n        } catch (final NumberFormatException ex) {\n            throw new IllegalArgumentException(String.format(\"System property `%s` must be a positive integer, but was `%s`.\", propertyName, configuredValue), ex);\n        }\n        ShardingSpherePreconditions.checkState(result > 0,\n                () -> new IllegalArgumentException(String.format(\"System property `%s` must be a positive integer, but was `%s`.\", propertyName, configuredValue)));\n        return result;\n    }\n    \n    /**\n     * Create tool call limit payload.\n     *\n     * @return tool call limit payload\n     */\n    public static Map<String, Object> createToolCallLimitPayload() {\n        Map<String, Object> result = new LinkedHashMap<>(4, 1F);\n        result.put(\"scope\", \"session\");\n        result.put(\"max_calls\", getMaxToolCallsPerSession());\n        result.put(\"property\", MAX_TOOL_CALLS_PER_SESSION_PROPERTY);\n        result.put(MCPPayloadFieldNames.RECOVERY, \"Close and recreate the MCP session after the quota is exhausted.\");\n        return result;","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/security/MCPRuntimeProtectionPolicy.java#L59-L95","documentation":"Thrown by MCPRuntimeProtectionPolicy.getPositiveIntegerProperty when a system property that tunes runtime protection limits (e.g. max completion requests per minute) is set but is either not parsable as an integer (NumberFormatException path, with cause attached) or parses to a value <= 0 (checkState path). The property name and the offending value are both included in the message.","triggerScenarios":"Starting the MCP server with -Dmcp.<limit-property>=abc, =10.5, =-1, or =0 (with the exact property name from the constant, e.g. MAX_COMPLETION_REQUESTS_PER_MINUTE_PROPERTY). Unset properties are fine — the code default is used.","commonSituations":"Tuning rate-limit properties via JAVA_OPTS or JVM flags with a typo or wrong format (percent signs, decimals, empty string), or copying a 0 from a config that intended 'unlimited' — this policy treats non-positive as invalid by design.","solutions":["Fix the -D value to a positive integer, e.g. -D<property>=60.","Remove the property to use the built-in default if you do not need a custom limit.","Check for trailing whitespace/quotes in the JVM argument (shell quoting artifacts often land in the value, and the message shows the exact offending string)."],"exampleFix":"# before\nexport JAVA_TOOL_OPTIONS=\"-Dmcp.max.completion.requests.per.minute=0\"\n# after\nexport JAVA_TOOL_OPTIONS=\"-Dmcp.max.completion.requests.per.minute=60\"","handlingStrategy":"validation","validationCode":"String v = System.getProperty(propertyName);\nif (null != v && !v.trim().matches(\"[1-9]\\\\d*\")) throw new IllegalArgumentException(propertyName + \" must be a positive integer: \" + v);","typeGuard":null,"tryCatchPattern":"try {\n    MCPRuntimeProtectionPolicy.getMaxCompletionRequestsPerMinute();\n} catch (final IllegalArgumentException ex) {\n    // startup-time: fix or remove the -D flag named in the message and restart\n}","preventionTips":["Assert tuning properties are positive integers in deployment scripts","Prefer unset (use default) over guessing values","Watch for shell quoting artifacts in JVM options"],"tags":["mcp","configuration","system-property","startup"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}