alibaba/COLA · error · StateMachineException
There is no stateMachine instance for ${machineId}, please b
Error message
There is no stateMachine instance for ${machineId}, please build it first What it means
StateMachineFactory.get() looks up a built state machine by machineId in the static registry and throws this StateMachineException when no machine with that id has been built/registered. It is a lookup failure: the caller referenced a machine id that was never built in this JVM.
Source
Thrown at cola-components/cola-component-statemachine/src/main/java/com/alibaba/cola/statemachine/StateMachineFactory.java:28
*
* @author Frank Zhang
* @date 2020-02-08 10:21 PM
*/
public class StateMachineFactory {
static Map<String /* machineId */, StateMachine> stateMachineMap = new ConcurrentHashMap<>();
public static <S, E, C> void register(StateMachine<S, E, C> stateMachine){
String machineId = stateMachine.getMachineId();
if(stateMachineMap.get(machineId) != null){
throw new StateMachineException("The state machine with id ["+machineId+"] is already built, no need to build again");
}
stateMachineMap.put(stateMachine.getMachineId(), stateMachine);
}
public static <S, E, C> StateMachine<S, E, C> get(String machineId){
StateMachine stateMachine = stateMachineMap.get(machineId);
if(stateMachine == null){
throw new StateMachineException("There is no stateMachine instance for "+machineId+", please build it first");
}
return stateMachine;
}
}
View on GitHub (pinned to 352e1a8675)
Solutions
- Build the machine first via StateMachineBuilder before calling get(), with the exact same machineId
- Verify the machineId string matches the one used at build time (extract it to a constant)
- Check initialization ordering / ensure the builder bean is initialized before consumers call get()
Example fix
// before
StateMachine<...> sm = StateMachineFactory.get("orderSM"); // never built -> throws
// after
StateMachine<...> sm = StateMachineFactory.get(STATE_MACHINE_ID);
if (sm == null) {
sm = buildOrderStateMachine(STATE_MACHINE_ID);
} Defensive patterns
Strategy: validation
Validate before calling
StateMachine sm = StateMachineFactory.get(machineId);
if (sm == null) {
throw new IllegalStateException("Build state machine first: " + machineId);
} Try / catch
try {
sm = StateMachineFactory.get(machineId);
} catch (StateMachineException e) {
if (e.getMessage().contains("please build it first")) {
sm = buildStateMachine(machineId); // build then retry
} else {
throw e;
}
} Prevention
- Always build before get, or get-and-build-if-null
- Extract machineId strings into shared constants
- Verify builder code runs in the same JVM as consumers
- Check startup initialization ordering
When it happens
Trigger: Calling StateMachineFactory.get("someId") before building the machine, with a typo in the machineId, or after the building code never ran (e.g. missing configuration/bean initialization).
Common situations: Typos or renamed machine ids; consumer code running in a different JVM/module than the builder; startup ordering where get() runs before build().
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- The state machine with id [${machineId}] is already built, n
- ${currentStateId} is not found, please check state machine
- Cannot fire event [${event}] on current state [${sourceState
- ${transition} already Exist, you can not add another one
- State machine is not built yet, can not work
AI-assisted analysis of alibaba/COLA@352e1a8675 (2026-09-08).
Data as JSON: /api/errors/9ef1083a2ab6c0a1.
Report an issue: GitHub.