conductor-oss/conductor · error · IllegalArgumentException
Unknown termination type in composite: ${type}
Error message
Unknown termination type in composite: ${type} What it means
Thrown by buildSubConditionBody() when iterating sub-conditions inside a composite termination ('and'/'or') and encountering a sub-condition whose type is not one of the six supported values. This is the same validation as error 33 but applied to each entry in a composite's conditions list.
Source
Thrown at agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/compiler/TerminationCompiler.java:318
/**
* Build the inline JavaScript body for a single sub-condition within a composite. Each
* sub-condition evaluates to a local variable {@code rN} containing {@code {should_continue,
* reason}}.
*/
private static String buildSubConditionBody(TerminationConfig sub, int index) {
String varName = "r" + index;
String type = sub.getType();
return switch (type) {
case "text_mention" -> buildInlineTextMention(sub, varName);
case "stop_message" -> buildInlineStopMessage(sub, varName);
case "max_message" -> buildInlineMaxMessage(sub, varName);
case "token_usage" -> buildInlineTokenUsage(sub, varName);
case "and" -> buildInlineComposite(sub, varName, true, index);
case "or" -> buildInlineComposite(sub, varName, false, index);
default ->
throw new IllegalArgumentException(
"Unknown termination type in composite: " + type);
};
}
private static String buildInlineTextMention(TerminationConfig config, String varName) {
String textJs = JavaScriptBuilder.toJson(config.getText());
boolean caseSensitive =
config.getCaseSensitive() != null ? config.getCaseSensitive() : true;
return " var "
+ varName
+ " = (function() {"
+ " var content = String($.result || '');"
+ " var text = "
+ textJs
+ ";"
+ " var caseSensitive = "
+ caseSensitiveView on GitHub (pinned to cf7c3e4a8a)
Solutions
- Inspect each sub-condition in the composite's conditions list and verify its type is one of: text_mention, stop_message, max_message, token_usage, and, or.
- Check for null type values in sub-conditions.
- Fix the specific sub-condition whose type is invalid.
Example fix
// before: sub-condition has typo "token" instead of "token_usage"
TerminationConfig.builder()
.type("or")
.conditions(List.of(
TerminationConfig.builder().type("max_message").maxMessages(10).build(),
TerminationConfig.builder().type("token").maxTotalTokens(5000).build())) // typo!
.build();
// after
TerminationConfig.builder()
.type("or")
.conditions(List.of(
TerminationConfig.builder().type("max_message").maxMessages(10).build(),
TerminationConfig.builder().type("token_usage").maxTotalTokens(5000).build()))
.build(); Defensive patterns
Strategy: validation
Validate before calling
private static final Set<String> VALID_TERM_TYPES =
Set.of("text_mention", "stop_message", "max_message", "token_usage", "and", "or");
void validateSubConditions(TerminationConfig composite) {
if (composite.getConditions() == null) return;
for (int i = 0; i < composite.getConditions().size(); i++) {
TerminationConfig sub = composite.getConditions().get(i);
if (sub.getType() == null || !VALID_TERM_TYPES.contains(sub.getType())) {
throw new IllegalArgumentException(
"conditions[" + i + "] has unknown type: " + sub.getType());
}
}
} Type guard
static boolean allSubConditionsValid(TerminationConfig composite) {
if (!Set.of("and", "or").contains(composite.getType())) return true;
if (composite.getConditions() == null) return false;
return composite.getConditions().stream().allMatch(
c -> VALID_TERM_TYPES.contains(c.getType()));
} Try / catch
try {
String script = TerminationCompiler.buildTerminationScript(compositeConfig);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Unknown termination type in composite")) {
// find and fix the sub-condition with the bad type
}
throw e;
} Prevention
- Validate every sub-condition's type when building composites.
- Use constants or enums for termination type strings.
- Log sub-condition types during construction to catch null values early.
When it happens
Trigger: A composite TerminationConfig (type='and' or 'or') whose conditions list contains at least one TerminationConfig with a null or unrecognized type string.
Common situations: One sub-condition in a composite has a typo in its type (e.g., 'token' instead of 'token_usage'), or a sub-condition was added with a null type. This is harder to spot because the error surfaces only when the composite is compiled, not when each sub-condition is defined.
Related errors
- Composite termination (${isAnd ? "and" : "or"}) must have at
- Composite termination must have at least one sub-condition
- Unknown termination type in nested composite: ${type}
- Unknown termination type: ${type}
- SWARM handoff type must be on_tool_result, on_text_mention,
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/aeb2a18ccc48f845.
Report an issue: GitHub.