{"record":{"id":"9ba823324d7a95fd","repo":"apache/shardingsphere","slug":"statement-is-not-supported-by-the-mcp-contract-9ba823","errorCode":null,"errorMessage":"Statement is not supported by the MCP contract.","messagePattern":"Statement is not supported by the MCP contract\\.","errorType":"exception","errorClass":"MCPUnsupportedSQLStatementException","httpStatus":null,"severity":"error","filePath":"mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/SQLStatementScanner.java","lineNumber":106,"sourceCode":"        return sql;\n    }\n    \n    SQLStatementScanner scan(final String sql) {\n        return new SQLStatementScanner(lexerClass, parserClass, sql);\n    }\n    \n    String leadingSql() {\n        return sql.substring(visibleTokens.isEmpty() ? sql.length() : visibleTokens.get(0).getStartIndex()).trim();\n    }\n    \n    String extractLeadingKeyword() {\n        int startIndex = visibleTokens.isEmpty() ? sql.length() : visibleTokens.get(0).getStartIndex();\n        int stopIndex = startIndex;\n        while (stopIndex < sql.length() && Character.isLetter(sql.charAt(stopIndex))) {\n            stopIndex++;\n        }\n        if (startIndex == stopIndex) {\n            throw new MCPUnsupportedSQLStatementException();\n        }\n        return sql.substring(startIndex, stopIndex).toUpperCase(Locale.ENGLISH);\n    }\n    \n    boolean containsExecutableComment() {\n        return executableComment;\n    }\n    \n    private boolean containsExecutableComment(final String sql, final List<Token> tokens, final boolean lineCommentsHandledByLexer) {\n        int nextIndex = 0;\n        int skippedCommentEnd = -1;\n        for (int index = 0; index < tokens.size(); index++) {\n            Token each = tokens.get(index);\n            if (each.getStartIndex() <= skippedCommentEnd) {\n                continue;\n            }\n            if (each.getStartIndex() > nextIndex && containsExecutableCommentMarker(sql.substring(nextIndex, each.getStartIndex()))) {\n                return true;","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/SQLStatementScanner.java#L88-L124","documentation":"Thrown by SQLStatementScanner.extractLeadingKeyword as MCPUnsupportedSQLStatementException when the scanner cannot extract any leading alphabetic keyword from the statement. If the first visible token starts with a non-letter (digit, punctuation, paren) or the statement has no visible tokens at all, keyword extraction yields an empty span and the statement is declared unsupported.","triggerScenarios":"visibleTokens is empty (comment-only or whitespace-only input), or the character at the first visible token's start index is not a letter — e.g. `(SELECT 1)`, `123 + 1`, `@x`, `$func$ ...`, `\"quoted\" ...` as the leading text. startIndex == stopIndex triggers the throw.","commonSituations":"Statements wrapped in parentheses for precedence; expressions starting with literals or variables; empty/comment-only payloads sent by an agent loop; strings whose leading quote/backtick survives as the first token (also caught separately by delimiter validation).","solutions":["Rewrite the statement so it begins with a SQL keyword: unwrap `(SELECT ...)` to `SELECT ...`, drop leading literals","Ensure the payload actually contains a statement, not only comments or whitespace","If you need expression evaluation, wrap it as `SELECT <expr>` before submitting"],"exampleFix":"-- before\n(SELECT * FROM t_order) LIMIT 10\n\n-- after\nSELECT * FROM t_order LIMIT 10","handlingStrategy":"validation","validationCode":"// Require the first non-space, non-comment character to be a letter\nString stripped = sql.strip();\nif (stripped.isEmpty() || !Character.isLetter(stripped.charAt(0))) {\n    throw new IllegalArgumentException(\"Statement must start with a SQL keyword; wrap expressions in SELECT\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    executeSql(sql);\n} catch (MCPUnsupportedSQLStatementException e) {\n    executeSql(\"SELECT \" + sql.strip().replaceFirst(\"^\\\\(|\\\\)$\", \"\")); // normalize leading keyword\n}","preventionTips":["Always prefix expression-only payloads with SELECT","Unwrap parenthesized statements before submission"],"tags":["mcp","sql-scanner","unsupported-statement","shardingsphere"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}