{"record":{"id":"cf188507ce2ced81","repo":"spring-projects/spring-ai","slug":"no-calladvisors-available-to-execute","errorCode":null,"errorMessage":"No CallAdvisors available to execute","messagePattern":"No CallAdvisors available to execute","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/DefaultAroundAdvisorChain.java","lineNumber":102,"sourceCode":"\t\tthis.observationRegistry = observationRegistry;\n\t\tthis.callAdvisors = callAdvisors;\n\t\tthis.streamAdvisors = streamAdvisors;\n\t\tthis.originalCallAdvisors = List.copyOf(callAdvisors);\n\t\tthis.originalStreamAdvisors = List.copyOf(streamAdvisors);\n\t\tthis.observationConvention = observationConvention != null ? observationConvention\n\t\t\t\t: DEFAULT_OBSERVATION_CONVENTION;\n\t}\n\n\tpublic static Builder builder(ObservationRegistry observationRegistry) {\n\t\treturn new Builder(observationRegistry);\n\t}\n\n\t@Override\n\tpublic ChatClientResponse nextCall(ChatClientRequest chatClientRequest) {\n\t\tAssert.notNull(chatClientRequest, \"the chatClientRequest cannot be null\");\n\n\t\tif (this.callAdvisors.isEmpty()) {\n\t\t\tthrow new IllegalStateException(\"No CallAdvisors available to execute\");\n\t\t}\n\n\t\tvar advisor = this.callAdvisors.pop();\n\n\t\tvar observationContext = AdvisorObservationContext.builder()\n\t\t\t.advisorName(advisor.getName())\n\t\t\t.chatClientRequest(chatClientRequest)\n\t\t\t.order(advisor.getOrder())\n\t\t\t.build();\n\n\t\treturn AdvisorObservationDocumentation.AI_ADVISOR\n\t\t\t.observation(this.observationConvention, DEFAULT_OBSERVATION_CONVENTION, () -> observationContext,\n\t\t\t\t\tthis.observationRegistry)\n\t\t\t.observe(() -> {\n\t\t\t\tvar chatClientResponse = advisor.adviseCall(chatClientRequest, this);\n\t\t\t\tobservationContext.setChatClientResponse(chatClientResponse);\n\t\t\t\treturn chatClientResponse;\n\t\t\t});","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/DefaultAroundAdvisorChain.java#L84-L120","documentation":"DefaultAroundAdvisorChain.nextCall() requires at least one CallAdvisor in the chain; calling nextCall on an empty chain throws IllegalStateException('No CallAdvisors available to execute'). The chain terminates advisor execution by design, and an empty chain means there is nothing to dispatch the request to.","triggerScenarios":"Invoking nextCall() on a DefaultAroundAdvisorChain built without any CallAdvisors, or after all advisors have already been popped, or calling nextCall twice on the same chain.","commonSituations":"Building an advisor chain with only StreamRequestResponseAdvisors (no call advisors), reusing a chain across two calls so it's already drained, or misusing the internal API directly in tests.","solutions":["Register at least one CallAdvisor when building the chain (e.g. ToolAdvisor or a request/response advisor).","Create a fresh chain per request instead of reusing a popped/drained chain instance.","If you only need streaming, use the stream path rather than nextCall.","Check the chain's size/emptiness before invoking nextCall in custom code."],"exampleFix":"// before\nvar chain = DefaultAroundAdvisorChain.builder(registry).build();\nchain.nextCall(request);\n// after\nvar chain = DefaultAroundAdvisorChain.builder(registry)\n    .advisors(List.of(myCallAdvisor)).build();\nchain.nextCall(request);","handlingStrategy":"validation","validationCode":"if (chain == null /* or chain size not yet known */) {\n  // build the chain with at least one CallAdvisor before calling nextCall\n}\nvar chain = DefaultAroundAdvisorChain.builder(registry).advisors(List.of(callAdvisor)).build();","typeGuard":null,"tryCatchPattern":"try { chain.nextCall(request); } catch (IllegalStateException e) { if (e.getMessage().contains(\"No CallAdvisors\")) { /* rebuild chain with advisors */ } throw e; }","preventionTips":["Always register at least one CallAdvisor in the chain.","Never reuse a chain instance after it has been drained; build a new one per request.","Use the stream API for streaming flows instead of nextCall."],"tags":["advisor-chain","spring-ai"],"backgroundTag":"invalid-state-transition","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"}