apache/incubator-seata · error · IllegalArgumentException
Unknown StateType[{value}]
Error message
Unknown StateType[{value}] What it means
Thrown by StateType.getStateType(String) when the supplied string does not case-insensitively match any known state type value (ServiceTask, Choice, Fail, Succeed, CompensationTrigger, SubStateMachine, SubStateMachineCompensation, ScriptTask, LoopStart). This is the parser entry point for state machine JSON definitions, so in practice the exception means a 'Type' field in your saga JSON is misspelled or unsupported by this Seata version.
Source
Thrown at compatible/src/main/java/io/seata/saga/statelang/domain/StateType.java:87
private String value;
StateType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static StateType getStateType(String value) {
for (StateType stateType : values()) {
if (stateType.getValue().equalsIgnoreCase(value)) {
return stateType;
}
}
throw new IllegalArgumentException("Unknown StateType[" + value + "]");
}
public static StateType wrap(org.apache.seata.saga.statelang.domain.StateType target) {
if (target == null) {
return null;
}
switch (target) {
case SERVICE_TASK:
return SERVICE_TASK;
case CHOICE:
return CHOICE;
case FAIL:
return FAIL;
case SUCCEED:
return SUCCEED;
case COMPENSATION_TRIGGER:
return COMPENSATION_TRIGGER;
case SUB_STATE_MACHINE:View on GitHub (pinned to e01f97c6db)
Solutions
- Open the state machine JSON referenced in the stack trace and check the failing state's "Type" against the supported list: ServiceTask, Choice, Fail, Succeed, CompensationTrigger, SubStateMachine, SubStateMachineCompensation, ScriptTask, LoopStart (matching is case-insensitive but otherwise exact).
- Upgrade the Seata saga engine to a version that supports the state type you are using (e.g. ScriptTask requires Seata >= 1.5/2.x).
- Add a startup validation pass that parses all state machine definitions before serving traffic, so typos fail deployment instead of at runtime.
- If the JSON is machine-generated, fix the generator to emit canonical type names.
Example fix
// before (statelang/example.json)
{
"Name": "demo", "Comment": "demo",
"StartState": "Check",
"States": {
"Check": { "Type": "ServcieTask", "ServiceName": "checkService", ... }
}
}
// after
{
"Name": "demo", "Comment": "demo",
"StartState": "Check",
"States": {
"Check": { "Type": "ServiceTask", "ServiceName": "checkService", ... }
}
} Defensive patterns
Strategy: validation
Validate before calling
private static final Set<String> VALID = Set.of(
"ServiceTask", "Choice", "Fail", "Succeed", "CompensationTrigger",
"SubStateMachine", "SubStateMachineCompensation", "ScriptTask", "LoopStart");
public static void validateStateMachineJson(JsonNode definition) {
definition.path("States").forEach(state -> {
String type = state.path("Type").asText(null);
if (type == null || VALID.stream().noneMatch(v -> v.equalsIgnoreCase(type.trim()))) {
throw new IllegalArgumentException("Invalid state Type '" + type
+ "' in state machine '" + definition.path("Name").asText() + "'");
}
});
} Type guard
public static boolean isKnownStateType(String value) {
if (value == null) return false;
String v = value.trim();
for (StateType t : StateType.values()) {
if (t.getValue().equalsIgnoreCase(v)) return true;
}
return false;
} Try / catch
try {
StateType t = StateType.getStateType(typeString);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("State '" + stateName + "' has invalid Type '"
+ typeString + "'; expected one of ServiceTask, Choice, Fail, Succeed, "
+ "CompensationTrigger, SubStateMachine, SubStateMachineCompensation, ScriptTask, LoopStart", e);
} Prevention
- Validate all saga JSON definitions at deploy time, not on first execution.
- Keep definitions in version control and lint the 'Type' field in CI.
- Check the Seata release notes before adopting new state types (e.g. ScriptTask) so engine and definitions stay compatible.
- Remember matching is case-insensitive but whitespace-sensitive — trim editor artifacts.
When it happens
Trigger: Loading a state machine definition (e.g. StateMachineImpl/StatelangStateMachineRepository parsing the JSON from the classpath or config center) whose state entry has "Type": "ServcieTask" (typo), "CompensationTrigger " (trailing space), or a newer type like "ScriptTask" used against an older Seata that lacks it. Direct calls to StateType.getStateType("bogus") reproduce it immediately.
Common situations: Hand-edited saga JSON files; state machines authored for a newer Seata version (ScriptTask exists only in newer releases) deployed on an older engine; JSON produced by external tooling that uses different type names; extra whitespace or encoding issues (BOM) in the type field.
Related errors
- unknown di for element ${semantic.id}
- Invalid port number in: {}
- Invalid format for endpoint: {}
- "\"" + str + "\" can't parse to Duration"
- datasource required not null!
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/c0f1cd48286d906d.
Report an issue: GitHub.