{"record":{"id":"212a3a114ef5032b","repo":"spring-projects/spring-ai","slug":"progress-notification-not-supported-by-the-client-212a3a","errorCode":null,"errorMessage":"Progress notification not supported by the client!","messagePattern":"Progress notification not supported by the client!","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/context/DefaultMcpSyncRequestContext.java","lineNumber":290,"sourceCode":"\n\t@Override\n\tpublic void progress(int percentage) {\n\t\tAssert.isTrue(percentage >= 0 && percentage <= 100, \"Percentage must be between 0 and 100\");\n\t\tthis.progress(p -> p.progress(percentage / 100.0).total(1.0).message(null));\n\t}\n\n\t@Override\n\tpublic void progress(Consumer<ProgressSpec> progressSpec) {\n\n\t\tAssert.notNull(progressSpec, \"Progress spec consumer must not be null\");\n\t\tDefaultProgressSpec spec = new DefaultProgressSpec();\n\n\t\tprogressSpec.accept(spec);\n\n\t\tvar progressToken = this.request.progressToken();\n\n\t\tif (progressToken == null || (progressToken instanceof String pt && !Utils.hasText(pt))) {\n\t\t\tlogger.warn(\"Progress notification not supported by the client!\");\n\t\t\treturn;\n\t\t}\n\n\t\tthis.progress(new ProgressNotification(progressToken, spec.progress, spec.total, spec.message, spec.meta));\n\t}\n\n\t@Override\n\tpublic void progress(ProgressNotification progressNotification) {\n\t\tthis.exchange.progressNotification(progressNotification);\n\t}\n\n\t// Ping\n\n\t@Override\n\tpublic void ping() {\n\t\tthis.exchange.ping();\n\t}\n","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/context/DefaultMcpSyncRequestContext.java#L272-L308","documentation":"In DefaultMcpSyncRequestContext.progress(), when the incoming request carries no progress token (null or blank), the client cannot be notified of progress. The method logs a warning and returns immediately without sending anything; the tool invocation itself is unaffected.","triggerScenarios":"Calling ctx.progress(spec -> spec.progress(...)) inside a sync @McpTool method when the client's tool-call request did not include a progressToken in _meta.","commonSituations":"Testing with clients that don't attach progress tokens; combining tool code that always reports progress with clients (e.g. simple REST calls) that don't support notifications.","solutions":["Have the client include \"_meta\": { \"progressToken\": \"...\" } in the tools/call request","Skip progress reporting or make it conditional when progress is optional","Ignore the warning — it indicates a silent no-op, not a failed tool execution"],"exampleFix":"// before\nctx.progress(p -> p.progress(1).total(3));\n// after\n// client side: { \"name\": \"tool\", \"arguments\": {...}, \"_meta\": { \"progressToken\": \"p1\" } }","handlingStrategy":"fallback","validationCode":"// client side: include _meta.progressToken in tools/call request\n// { \"name\": \"tool\", \"arguments\": {...}, \"_meta\": { \"progressToken\": \"p1\" } }","typeGuard":"static boolean hasProgressToken(Object token) {\n  return token != null && (!(token instanceof String s) || !s.isBlank());\n}","tryCatchPattern":null,"preventionTips":["Ensure the calling client sets a progressToken for long-running tools","Design tools so progress reporting is optional","Ignore this warning when progress is not needed — execution is unaffected"],"tags":["spring-ai","mcp","progress-notification","sync-context"],"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-23T08:17:48.524Z"}