-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Please do a quick search on GitHub issues first, there might be already a duplicate issue for the one you are about to create.
If the bug is trivial, just go ahead and create the issue. Otherwise, please take a few moments and fill in the following sections:
Bug description
Getting this exception:
Invalid schema for function 'xxx': In context=(), object schema missing properties.
I think this happens only when the tool has no parameters. Check the example below:
2025-10-31T13:46:54.123Z WARN 41701 --- [agent] [pool-4-thread-1] o.s.a.r.a.SpringAiRetryAutoConfiguration : Retry error. Retry count: 1, Exception: HTTP 400 - {
"error": {
"message": "Invalid schema for function 'k8s_get_available_api_resources': In context=(), object schema missing properties.",
"type": "invalid_request_error",
"param": "tools[9].function.parameters",
"code": "invalid_function_parameters"
}
}
org.springframework.ai.retry.NonTransientAiException: HTTP 400 - {
"error": {
"message": "Invalid schema for function 'k8s_get_available_api_resources': In context=(), object schema missing properties.",
"type": "invalid_request_error",
"param": "tools[9].function.parameters",
"code": "invalid_function_parameters"
}
}
at org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration$2.handleError(SpringAiRetryAutoConfiguration.java:109) ~[spring-ai-autoconfigure-retry-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:58) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.StatusHandler.lambda$fromErrorHandler$1(StatusHandler.java:71) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.StatusHandler.handle(StatusHandler.java:146) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.applyStatusHandlers(DefaultRestClient.java:838) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.lambda$readBody$4(DefaultRestClient.java:827) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:216) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:826) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.lambda$toEntityInternal$2(DefaultRestClient.java:782) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:586) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchange(DefaultRestClient.java:540) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.RestClient$RequestHeadersSpec.exchange(RestClient.java:680) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.executeAndExtract(DefaultRestClient.java:821) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.toEntityInternal(DefaultRestClient.java:781) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.toEntity(DefaultRestClient.java:770) ~[spring-web-6.2.11.jar:6.2.11]
at org.springframework.ai.openai.api.OpenAiApi.chatCompletionEntity(OpenAiApi.java:212) ~[spring-ai-openai-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at org.springframework.ai.openai.OpenAiChatModel.lambda$internalCall$1(OpenAiChatModel.java:200) ~[spring-ai-openai-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:357) ~[spring-retry-2.0.12.jar:na]
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:230) ~[spring-retry-2.0.12.jar:na]
at org.springframework.ai.openai.OpenAiChatModel.lambda$internalCall$3(OpenAiChatModel.java:200) ~[spring-ai-openai-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.15.4.jar:1.15.4]
at org.springframework.ai.openai.OpenAiChatModel.internalCall(OpenAiChatModel.java:197) ~[spring-ai-openai-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at org.springframework.ai.openai.OpenAiChatModel.call(OpenAiChatModel.java:182) ~[spring-ai-openai-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at org.springframework.ai.chat.client.advisor.ChatModelCallAdvisor.adviseCall(ChatModelCallAdvisor.java:54) ~[spring-ai-client-chat-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextCall$1(DefaultAroundAdvisorChain.java:113) ~[spring-ai-client-chat-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.15.4.jar:1.15.4]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextCall(DefaultAroundAdvisorChain.java:112) ~[spring-ai-client-chat-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.lambda$doGetObservableChatClientResponse$1(DefaultChatClient.java:520) ~[spring-ai-client-chat-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.15.4.jar:1.15.4]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetObservableChatClientResponse(DefaultChatClient.java:518) ~[spring-ai-client-chat-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetObservableChatClientResponse(DefaultChatClient.java:497) ~[spring-ai-client-chat-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.content(DefaultChatClient.java:492) ~[spring-ai-client-chat-1.1.0-SNAPSHOT.jar:1.1.0-SNAPSHOT]
at com.salaboy.platform.agent.CheckPlatformCapabilitiesActivity.run(CheckPlatformCapabilitiesActivity.java:42) ~[classes/:na]
at io.dapr.workflows.runtime.WorkflowActivityInstanceWrapper.lambda$create$0(WorkflowActivityInstanceWrapper.java:54) ~[dapr-sdk-workflows-1.16.1-rc-2.jar:na]
at io.dapr.durabletask.TaskActivityExecutor.execute(TaskActivityExecutor.java:38) ~[durabletask-client-1.5.10.jar:na]
at io.dapr.durabletask.DurableTaskGrpcWorker.lambda$startAndBlock$1(DurableTaskGrpcWorker.java:199) ~[durabletask-client-1.5.10.jar:na]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]
Request:
{
"method": "tools/call",
"params": {
"name": "k8s_get_available_api_resources",
"arguments": {},
"_meta": {
"progressToken": 2
}
}
}
Response:
{
"content": [
{
"type": "text",
"text": "NAME SHORTNAMES APIVERSION NAMESPACED KIND\nbindings v1 true Binding\ncomponentstatuses cs v1 false ComponentStatus\nconfigmaps cm v1 true ConfigMap\nendpoints ep v1 true Endpoints\nevents ev v1 true Event\nlimitranges limits v1 true LimitRange\nnamespaces ns v1 false Namespace\nnodes no v1 false Node\npersistentvolumeclaims pvc v1 true PersistentVolumeClaim\npersistentvolumes pv v1 false PersistentVolume\npods po v1 true Pod\npodtemplates v1 true PodTemplate\nreplicationcontrollers rc v1 true ReplicationController\nresourcequotas quota v1 true ResourceQuota\nsecrets v1 true Secret\nserviceaccounts sa v1 true ServiceAccount\nservices svc v1 true Service\nmutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration\nvalidatingadmissionpolicies admissionregistration.k8s.io/v1 false ValidatingAdmissionPolicy\nvalidatingadmissionpolicybindings admissionregistration.k8s.io/v1 false ValidatingAdmissionPolicyBinding\nvalidatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration\ncustomresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition\napiservices apiregistration.k8s.io/v1 false APIService\ncontrollerrevisions apps/v1 true ControllerRevision\ndaemonsets ds apps/v1 true DaemonSet\ndeployments deploy apps/v1 true Deployment\nreplicasets rs apps/v1 true ReplicaSet\nstatefulsets sts apps/v1 true StatefulSet\nselfsubjectreviews authentication.k8s.io/v1 false SelfSubjectReview\ntokenreviews authentication.k8s.io/v1 false TokenReview\nlocalsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview\nselfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview\nselfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview\nsubjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview\nhorizontalpodautoscalers hpa autoscaling/v2 true HorizontalPodAutoscaler\ncronjobs cj batch/v1 true CronJob\njobs batch/v1 true Job\ncertificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest\nleases coordination.k8s.io/v1 true Lease\nendpointslices discovery.k8s.io/v1 true EndpointSlice\nevents ev events.k8s.io/v1 true Event\nflowschemas flowcontrol.apiserver.k8s.io/v1 false FlowSchema\nprioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1 false PriorityLevelConfiguration\nagents kagent.dev/v1alpha2 true Agent\nmcpservers kagent.dev/v1alpha1 true MCPServer\nmemories kagent.dev/v1alpha1 true Memory\nmodelconfigs mc kagent.dev/v1alpha2 true ModelConfig\nremotemcpservers rmcps kagent.dev/v1alpha2 true RemoteMCPServer\ntoolservers ts kagent.dev/v1alpha1 true ToolServer\ningressclasses networking.k8s.io/v1 false IngressClass\ningresses ing networking.k8s.io/v1 true Ingress\nipaddresses ip networking.k8s.io/v1 false IPAddress\nnetworkpolicies netpol networking.k8s.io/v1 true NetworkPolicy\nservicecidrs networking.k8s.io/v1 false ServiceCIDR\nruntimeclasses node.k8s.io/v1 false RuntimeClass\npoddisruptionbudgets pdb policy/v1 true PodDisruptionBudget\nclusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding\nclusterroles rbac.authorization.k8s.io/v1 false ClusterRole\nrolebindings rbac.authorization.k8s.io/v1 true RoleBinding\nroles rbac.authorization.k8s.io/v1 true Role\npriorityclasses pc scheduling.k8s.io/v1 false PriorityClass\ncsidrivers storage.k8s.io/v1 false CSIDriver\ncsinodes storage.k8s.io/v1 false CSINode\ncsistoragecapacities storage.k8s.io/v1 true CSIStorageCapacity\nstorageclasses sc storage.k8s.io/v1 false StorageClass\nvolumeattachments storage.k8s.io/v1 false VolumeAttachment\n"
}
]
}
Environment
Connecting Spring AI MCP Client to Kagent (https://kagent.dev) MCP Server.
Steps to reproduce
Steps to reproduce the issue.
Expected behavior
A clear and concise description of what you expected to happen.
Minimal Complete Reproducible example
Please provide a failing test or a minimal complete verifiable example that reproduces the issue.
Bug reports that are reproducible will take priority in resolution over reports that are not reproducible.