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

  1. 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).
  2. 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).
  3. Add a startup validation pass that parses all state machine definitions before serving traffic, so typos fail deployment instead of at runtime.
  4. 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

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


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/c0f1cd48286d906d. Report an issue: GitHub.