spring-projects/spring-ai · error · McpProgressMethodException
Error invoking progress method: {this.method.getName()}
Error message
Error invoking progress method: {this.method.getName()} What it means
When the annotated progress method itself throws while being reflectively invoked by AsyncMcpProgressMethodCallback.apply, the exception is wrapped in an McpProgressMethodException with this message naming the failing method. The original cause is attached, so it indicates a runtime failure inside user handler code, not a signature problem.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/progress/AsyncMcpProgressMethodCallback.java:109
try {
// Build arguments for the method call
Object[] args = this.buildArgs(this.method, null, notification);
// Invoke the method
this.method.setAccessible(true);
Object result = this.method.invoke(this.bean, args);
// Handle return type
if (result instanceof Mono) {
return (Mono<?>) result;
}
else {
// void return type
return Mono.empty();
}
}
catch (Exception e) {
throw new McpProgressMethodException("Error invoking progress method: " + this.method.getName(), e);
}
}).flatMap(mono -> mono.then());
}
/**
* Create a new builder.
* @return A new builder instance
*/
public static Builder builder() {
return new Builder();
}
/**
* Builder for creating AsyncMcpProgressMethodCallback instances.
* <p>
* This builder provides a fluent API for constructing AsyncMcpProgressMethodCallback
* instances with the required parameters.
*/View on GitHub (pinned to 98a7beda4f)
Solutions
- Inspect the cause chain of the McpProgressMethodException and fix the underlying exception in the handler method.
- Add defensive null/argument checks inside the progress handler before using notification values.
- Wrap risky handler logic in try-catch or onErrorResume to degrade gracefully instead of failing the notification.
Example fix
// before
public void onProgress(Double p, String token, String msg) {
tracker.update(token, p); // NPE if tracker not initialized
}
// after
public void onProgress(Double p, String token, String msg) {
if (tracker != null) tracker.update(token, p);
} Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try {
callback.accept(notification);
} catch (McpProgressMethodException e) {
log.error("Progress handler {} failed: {}", e.getMessage(), e.getCause(), e);
// do not rethrow if progress failure must not abort the main operation
} Prevention
- Make progress handlers defensive: null-check notification fields before use.
- Keep heavy or failing logic out of progress handlers; log and swallow non-critical failures.
- Add onErrorResume in reactive handler chains so Mono errors are handled locally.
When it happens
Trigger: The progress handler method (void or Mono-producing path) throws an exception during synchronous part of its execution when a ProgressNotification is applied via the callback.
Common situations: NPE inside the handler from unvalidated notification fields; illegalStateException from accessing closed resources; any user-code bug surfaced during progress delivery from a client (e.g. during long-running tool execution).
Related errors
- Error invoking prompt list changed consumer method:
- Error invoking resource list changed consumer method: " + th
- Error invoking complete method:
- Error invoking logging consumer method:
- First parameter must be of type Double or double: {method.ge
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/4cdf23e56d1a7f04.
Report an issue: GitHub.