{"record":{"id":"03374dce4172cc74","repo":"spring-projects/spring-ai","slug":"sampling-not-supported-by-the-client","errorCode":null,"errorMessage":"Sampling not supported by the client: ","messagePattern":"Sampling 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":238,"sourceCode":"\n\t// Sampling\n\n\t@Override\n\tpublic boolean sampleEnabled() {\n\t\treturn !(this.exchange.getClientCapabilities() == null\n\t\t\t\t|| this.exchange.getClientCapabilities().sampling() == null);\n\t}\n\n\t@Override\n\tpublic CreateMessageResult sample(String... messages) {\n\t\treturn this.sample(s -> s.message(messages));\n\t}\n\n\t@Override\n\tpublic CreateMessageResult sample(Consumer<SamplingSpec> samplingSpec) {\n\n\t\tif (!this.sampleEnabled()) {\n\t\t\tthrow new IllegalStateException(\"Sampling not supported by the client: \" + this.exchange.getClientInfo());\n\t\t}\n\n\t\tAssert.notNull(samplingSpec, \"Sampling spec consumer must not be null\");\n\n\t\tDefaultSamplingSpec spec = new DefaultSamplingSpec();\n\t\tsamplingSpec.accept(spec);\n\n\t\tvar progressToken = this.request.progressToken();\n\n\t\treturn this.sample(McpSchema.CreateMessageRequest\n\t\t\t.builder(spec.messages, spec.maxTokens != null && spec.maxTokens > 0 ? spec.maxTokens : 500)\n\t\t\t.modelPreferences(spec.modelPreferences)\n\t\t\t.systemPrompt(spec.systemPrompt)\n\t\t\t.temperature(spec.temperature)\n\t\t\t.stopSequences(spec.stopSequences.isEmpty() ? null : spec.stopSequences)\n\t\t\t.includeContext(spec.includeContextStrategy)\n\t\t\t.meta(spec.metadata.isEmpty() ? null : spec.metadata)\n\t\t\t.progressToken(progressToken)","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/context/DefaultMcpSyncRequestContext.java#L220-L256","documentation":"DefaultMcpSyncRequestContext.sample(Consumer<SamplingSpec>) throws IllegalStateException when the connected MCP client has not declared support for sampling. The MCP server can only request LLM completions ('create message') via the client if the client's capabilities include sampling. The client info is appended to the message for diagnostics.","triggerScenarios":"Calling ctx.sample(specConsumer) from a @McpTool or other annotated handler when the exchange's client capabilities do not include sampling (sampleEnabled() returns false). Typically happens with clients that never enabled sampling in their initialize request.","commonSituations":"A server tool tries to delegate work to the client's LLM, but the client is a plain MCP host built without sampling enabled (sampling capability not set), or a CLI/test client connects without sampling support. Also occurs after client library upgrades where sampling capability flags reset.","solutions":["Enable sampling on the client side: include sampling capabilities when building the MCP client during client initialization and reconnect","Wrap sample() in a capability check (sampleEnabled()) and provide a fallback (local model call or default response) when sampling is unsupported","Verify the connected client is one that supports sampling; document the requirement or degrade tool behavior when it does not"],"exampleFix":"// before\nCreateMessageResult result = ctx.sample(spec -> spec.messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER, new McpSchema.TextContent(\"summarize\")))));\n// after\nCreateMessageResult result = ctx.sampleEnabled()\n    ? ctx.sample(spec -> spec.messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER, new McpSchema.TextContent(\"summarize\")))))\n    : fallbackSummarize();","handlingStrategy":"validation","validationCode":"if (!ctx.sampleEnabled()) { throw new ToolExecutionException(\"Client does not support sampling: \" + clientInfo); }","typeGuard":"boolean samplingAvailable = ctx.sampleEnabled();","tryCatchPattern":"try { return ctx.sample(spec); } catch (IllegalStateException e) { if (e.getMessage().startsWith(\"Sampling not supported\")) { return fallback(); } throw e; }","preventionTips":["Always enable sampling capability when constructing the MCP client if tools may sample","Check sampleEnabled() before any sample() call in server-side tool code","Document sampling requirements for each tool"],"tags":["mcp","sampling","illegal-state","client-capability"],"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-14T11:17:12.474Z"}