{"record":{"id":"18d299532769ba41","repo":"spring-projects/spring-ai","slug":"error-invoking-sampling-method-methodname","errorCode":null,"errorMessage":"Error invoking sampling method: {methodName}","messagePattern":"Error invoking sampling method: (.+?)","errorType":"exception","errorClass":"McpSamplingMethodException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/sampling/SyncMcpSamplingMethodCallback.java","lineNumber":72,"sourceCode":"\t@Override\n\tpublic CreateMessageResult apply(CreateMessageRequest request) {\n\t\tif (request == null) {\n\t\t\tthrow new IllegalArgumentException(\"Request must not be null\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Build arguments for the method call\n\t\t\tObject[] args = this.buildArgs(this.method, null, request);\n\n\t\t\t// Invoke the method\n\t\t\tthis.method.setAccessible(true);\n\t\t\tObject result = this.method.invoke(this.bean, args);\n\n\t\t\t// Return the result\n\t\t\treturn (CreateMessageResult) result;\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new McpSamplingMethodException(\"Error invoking sampling method: \" + this.method.getName(), e);\n\t\t}\n\t}\n\n\t/**\n\t * Validates that the method return type is compatible with the sampling callback.\n\t * @param method The method to validate\n\t * @throws IllegalArgumentException if the return type is not compatible\n\t */\n\t@Override\n\tprotected void validateReturnType(Method method) {\n\t\tClass<?> returnType = method.getReturnType();\n\n\t\tif (!CreateMessageResult.class.isAssignableFrom(returnType)) {\n\t\t\tthrow new IllegalArgumentException(\"Method must return CreateMessageResult: \" + method.getName() + \" in \"\n\t\t\t\t\t+ method.getDeclaringClass().getName() + \" returns \" + returnType.getName());\n\t\t}\n\t}\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/sampling/SyncMcpSamplingMethodCallback.java#L54-L90","documentation":"SyncMcpSamplingMethodCallback.apply() wraps any Exception thrown while reflectively invoking the sampling method into McpSamplingMethodException with message 'Error invoking sampling method: <methodName>'. This signals that the user's sampling handler method itself failed — the message carries the method name and the cause carries the original exception.","triggerScenarios":"The registered sampling method throws any Exception during method.invoke — e.g. NPE inside the handler, IO failure assembling the message, or a checked exception raised in the handler body.","commonSituations":"Handler logic bugs (null fields on the request), downstream API calls inside the handler failing, handler code throwing custom checked exceptions.","solutions":["Read getCause() on the McpSamplingMethodException to find the real failure","Fix the bug inside the sampling handler method named in the message","Add try/catch or validation inside the handler and return an error CreateMessageResult instead of throwing","Log the full stack trace with the cause chain before rethrowing"],"exampleFix":"// before\nCreateMessageResult sample(CreateMessageRequest req) {\n    return callModel(req); // throws IOException\n}\n// after\nCreateMessageResult sample(CreateMessageRequest req) {\n    try {\n        return callModel(req);\n    } catch (IOException e) {\n        throw new UncheckedIOException(e); // surfaces as cause\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    result = callback.apply(request);\n} catch (McpSamplingMethodException e) {\n    log.error(\"Sampling handler {} failed\", e.getMessage(), e.getCause());\n    return fallbackCreateMessageResult(request);\n}","preventionTips":["Keep handler methods small and validate inputs before heavy work","Catch and translate IO/checked exceptions inside the handler","Log the cause chain, not just the wrapper message"],"tags":["reflection","invocation-failure","sampling"],"backgroundTag":"api-request-failed","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}