{"record":{"id":"8ec98eb9821b0540","repo":"spring-projects/spring-ai","slug":"roots-not-supported-by-the-client","errorCode":null,"errorMessage":"Roots not supported by the client: ","messagePattern":"Roots not supported by the client: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/context/DefaultMcpSyncRequestContext.java","lineNumber":80,"sourceCode":"\tprivate DefaultMcpSyncRequestContext(McpSchema.Request request, McpSyncServerExchange exchange) {\n\t\tAssert.notNull(request, \"Request must not be null\");\n\t\tAssert.notNull(exchange, \"Exchange must not be null\");\n\t\tthis.request = request;\n\t\tthis.exchange = exchange;\n\t}\n\n\t// Roots\n\n\t@Override\n\tpublic boolean rootsEnabled() {\n\t\treturn !(this.exchange.getClientCapabilities() == null\n\t\t\t\t|| this.exchange.getClientCapabilities().roots() == null);\n\t}\n\n\t@Override\n\tpublic ListRootsResult roots() {\n\t\tif (!this.rootsEnabled()) {\n\t\t\tthrow new IllegalStateException(\"Roots not supported by the client: \" + this.exchange.getClientInfo());\n\t\t}\n\t\treturn this.exchange.listRoots();\n\t}\n\n\t// Elicitation\n\n\t@Override\n\tpublic boolean elicitEnabled() {\n\t\treturn !(this.exchange.getClientCapabilities() == null\n\t\t\t\t|| this.exchange.getClientCapabilities().elicitation() == null);\n\t}\n\n\t@Override\n\tpublic <T> StructuredElicitResult<T> elicit(Class<T> type) {\n\n\t\tif (!this.elicitEnabled()) {\n\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\"Elicitation not supported by the client: \" + this.exchange.getClientInfo());","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/context/DefaultMcpSyncRequestContext.java#L62-L98","documentation":"DefaultMcpSyncRequestContext.roots() requests the client's filesystem roots via the MCP roots capability. MCP clients must advertise the roots capability during initialization; when this client did not, the server cannot call listRoots, so an IllegalStateException is thrown including the client's ClientInfo.","triggerScenarios":"Server-side code calls context.roots() (or relies on roots implicitly) while handling a request from a client whose getClientCapabilities().roots() is null.","commonSituations":"Client (e.g. a minimal MCP host) initialized without declaring roots capability; older client library version that predates roots support; capability negotiation flags misconfigured on the client side.","solutions":["Enable the roots capability on the MCP client during initialization (e.g. set ClientCapabilities.builder().roots(true) or equivalent)","Check this.rootsEnabled() / context capability before calling roots() and degrade gracefully when unsupported","Upgrade or replace the client library/host if it does not support roots"],"exampleFix":"// before\nvar roots = context.roots();\n\n// after\nList<Root> roots = context.rootsEnabled()\n        ? context.roots().roots()\n        : List.of(); // fallback: no roots support","handlingStrategy":"try-catch","validationCode":"if (context.getClientCapabilities() == null\n        || context.getClientCapabilities().roots() == null) {\n    return List.of(); // skip roots-dependent logic\n}","typeGuard":"boolean rootsSupported(DefaultMcpSyncRequestContext ctx) {\n    return ctx.rootsEnabled();\n}","tryCatchPattern":"try {\n    ListRootsResult result = context.roots();\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Roots not supported\")) {\n        // proceed without roots\n    } else {\n        throw e;\n    }\n}","preventionTips":["Enable the roots capability on the client at initialization time","Gate roots usage behind a capability check on the server side","Document that server tools requiring roots need a roots-capable client"],"tags":["mcp","capability-negotiation","unsupported-operation"],"backgroundTag":"feature-not-enabled","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}