{"record":{"id":"113530a016e1dc44","repo":"alibaba/spring-ai-alibaba","slug":"no-default-output-or-error-next-node-provided","errorCode":null,"errorMessage":"No default output or error next node provided","messagePattern":"No default output or error next node provided","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/builder/generator/service/generator/workflow/sections/LLMNodeSection.java","lineNumber":140,"sourceCode":"\t\t\t\t\t\t            catch (Exception e) {\n\t\t\t\t\t\t                try {\n\t\t\t\t\t\t                    Thread.sleep(retryInterval);\n\t\t\t\t\t\t                } catch (InterruptedException ie) {\n\t\t\t\t\t\t                    Thread.currentThread().interrupt();\n\t\t\t\t\t\t                    break;\n\t\t\t\t\t\t                }\n\t\t\t\t\t\t            }\n\t\t\t\t\t\t        }\n\n\t\t\t\t\t\t        // error handling\n\t\t\t\t\t\t        if (defaultOutput != null) {\n\t\t\t\t\t\t            return %s;\n\t\t\t\t\t\t        }\n\t\t\t\t\t\t        else if (errorNextNode != null) {\n\t\t\t\t\t\t            return Map.of(nextNodeKey, errorNextNode);\n\t\t\t\t\t\t        }\n\t\t\t\t\t\t        else {\n\t\t\t\t\t\t            throw new IllegalStateException(\"No default output or error next node provided\");\n\t\t\t\t\t\t        }\n\t\t\t\t\t\t    };\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\"\"\",\n\t\t\t\tdialectType.equals(DSLDialectType.DIFY) ? \"Map.of(outputKeyPrefix + \\\"text\\\", content)\"\n\t\t\t\t\t\t: \"Map.of(outputKeyPrefix + \\\"output\\\", content, outputKeyPrefix + \\\"reasoning_content\\\", content)\",\n\t\t\t\tdialectType.equals(DSLDialectType.DIFY) ? \"Map.of(outputKeyPrefix + \\\"text\\\", defaultOutput)\"\n\t\t\t\t\t\t: \"Map.of(outputKeyPrefix + \\\"output\\\", defaultOutput, outputKeyPrefix + \\\"reasoning_content\\\", defaultOutput)\");\n\t}\n\n\t@Override\n\tpublic List<String> getImports() {\n\t\treturn List.of(\"org.springframework.ai.chat.messages.Message\",\n\t\t\t\t\"org.springframework.ai.chat.messages.AssistantMessage\",\n\t\t\t\t\"org.springframework.ai.chat.messages.MessageType\",\n\t\t\t\t\"org.springframework.ai.chat.messages.SystemMessage\",\n\t\t\t\t\"org.springframework.ai.chat.messages.UserMessage\",\n\t\t\t\t\"com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions\",","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/builder/generator/service/generator/workflow/sections/LLMNodeSection.java#L122-L158","documentation":"The generated LLM node's routing lambda requires either a default next node or an error next node to decide where to go after execution. If both are absent, the generated code throws IllegalStateException at runtime.","triggerScenarios":"An LLM node in the DSL has no downstream edge marked as the default/normal output and no error edge, and the generated routing function executes.","commonSituations":"Dangling LLM node at the end of an incomplete workflow graph; edges deleted during DSL editing; imported DSL where the LLM node is terminal but the generator still emits routing code.","solutions":["Add an outgoing edge from the LLM node to a downstream node (default output)","Configure an error next node so failures route to an error handler branch","Restructure the workflow so the LLM node is not unconditionally required to route"],"exampleFix":"// before\n{\"id\": \"llm1\", ...} // no outgoing edges\n// after\n{\"id\": \"llm1\", ...}, {\"source\": \"llm1\", \"target\": \"end1\", \"type\": \"default\"}","handlingStrategy":"validation","validationCode":"boolean hasOutgoingEdge = edges.stream().anyMatch(e -> e.getSource().equals(llmNodeId) && (\"default\".equals(e.getType()) || \"error\".equals(e.getType()))); if (!hasOutgoingEdge) { throw new IllegalArgumentException(\"LLM node needs a default or error edge: \" + llmNodeId); }","typeGuard":"null","tryCatchPattern":"try { stateRouter.apply(state); } catch (IllegalStateException e) { log.error(\"LLM node routing failed: {}\", e.getMessage()); }","preventionTips":["Validate graph connectivity before generation","Require terminal nodes to be explicit END nodes","Preserve default edges when editing imported DSLs"],"tags":["java","workflow","graph","routing"],"backgroundTag":"missing-required-argument","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}