{"record":{"id":"6a40f5cc02692d01","repo":"conductor-oss/conductor","slug":"unknown-termination-type-in-nested-composite-ty","errorCode":null,"errorMessage":"Unknown termination type in nested composite: ${type}","messagePattern":"Unknown termination type in nested composite: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/compiler/TerminationCompiler.java","lineNumber":468,"sourceCode":"        return sb.toString();\n    }\n\n    /**\n     * Build an inline sub-condition body for use inside a nested composite. Variable names are\n     * prefixed to avoid collisions.\n     */\n    private static String buildNestedSubConditionBody(\n            TerminationConfig sub, String varName, int parentIndex, int childIndex) {\n        String type = sub.getType();\n        return switch (type) {\n            case \"text_mention\" -> buildInlineTextMention(sub, varName);\n            case \"stop_message\" -> buildInlineStopMessage(sub, varName);\n            case \"max_message\" -> buildInlineMaxMessage(sub, varName);\n            case \"token_usage\" -> buildInlineTokenUsage(sub, varName);\n            case \"and\" -> buildInlineComposite(sub, varName, true, parentIndex * 10 + childIndex);\n            case \"or\" -> buildInlineComposite(sub, varName, false, parentIndex * 10 + childIndex);\n            default ->\n                    throw new IllegalArgumentException(\n                            \"Unknown termination type in nested composite: \" + type);\n        };\n    }\n}\n","sourceCodeStart":450,"sourceCodeEnd":473,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/compiler/TerminationCompiler.java#L450-L473","documentation":"Thrown by buildNestedSubConditionBody() when a sub-condition inside a nested composite (an and/or inside another and/or) has an unrecognized type. This is the same validation as errors 33/35 but for the deepest nesting level reached via the buildInlineComposite recursion path.","triggerScenarios":"A nested composite TerminationConfig whose conditions list contains a TerminationConfig with a null or unrecognized type string. The error is caught at the nested level (parentIndex > 0), distinguishing it from error 35 which fires at the first nesting level.","commonSituations":"Same as error 35 but occurring at a deeper nesting level. A sub-condition inside a nested composite has a typo or null type. Harder to debug because the nesting obscures which condition is invalid.","solutions":["Traverse the full termination tree to find the specific sub-condition at the deepest nesting level whose type is invalid.","Fix that sub-condition's type to one of: text_mention, stop_message, max_message, token_usage, and, or.","Use a recursive validator to catch all type errors before compilation."],"exampleFix":"// before: deepest nested sub has typo \"stop\" instead of \"stop_message\"\n// and > or > [max_message, stop]\n// after: fix \"stop\" to \"stop_message\"","handlingStrategy":"validation","validationCode":"private static final Set<String> VALID = Set.of(\n    \"text_mention\", \"stop_message\", \"max_message\", \"token_usage\", \"and\", \"or\");\n\nvoid validateAllNestedTypes(TerminationConfig config) {\n    if (config.getType() == null || !VALID.contains(config.getType())) {\n        throw new IllegalArgumentException(\"Invalid type at depth: \" + config.getType());\n    }\n    if (config.getConditions() != null) {\n        for (TerminationConfig sub : config.getConditions()) {\n            validateAllNestedTypes(sub);  // recurse into all nesting levels\n        }\n    }\n}","typeGuard":"static boolean allNestedTypesValid(TerminationConfig root) {\n    if (root.getType() == null || !VALID_TERM_TYPES.contains(root.getType())) return false;\n    if (root.getConditions() == null) return true;\n    return root.getConditions().stream().allMatch(x -> allNestedTypesValid(x));\n}","tryCatchPattern":"try {\n    String script = TerminationCompiler.buildTerminationScript(rootConfig);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Unknown termination type in nested composite\")) {\n        // recursively find the bad type at the deepest nesting level\n    }\n    throw e;\n}","preventionTips":["Run a recursive type validator over the entire termination tree before compiling.","For deeply nested composites, log the tree structure to aid debugging.","Minimize nesting depth — flatten where possible."],"tags":["termination","composite","nested","config-validation","agentspan"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}