flowable/flowable-engine · error · ActivitiIllegalArgumentException
type is null
Error message
type is null
What it means
ActivitiEventImpl is the base class of all engine events; its constructor requires a FlowableEngineEventType and rejects null with ActivitiIllegalArgumentException("type is null"). The event type drives listener dispatch, so an event without a type cannot be routed.
Source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/delegate/event/impl/ActivitiEventImpl.java:46
protected FlowableEngineEventType type;
protected String executionId;
protected String processInstanceId;
protected String processDefinitionId;
/**
* Creates a new event implementation, not part of an execution context.
*/
public ActivitiEventImpl(FlowableEngineEventType type) {
this(type, null, null, null);
}
/**
* Creates a new event implementation, part of an execution context.
*/
public ActivitiEventImpl(FlowableEngineEventType type, String executionId, String processInstanceId,
String processDefinitionId) {
if (type == null) {
throw new ActivitiIllegalArgumentException("type is null");
}
this.type = type;
this.executionId = executionId;
this.processInstanceId = processInstanceId;
this.processDefinitionId = processDefinitionId;
}
@Override
public FlowableEngineEventType getType() {
return type;
}
public void setType(FlowableEngineEventType type) {
this.type = type;
}
public String getExecutionId() {
return executionId;View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass a concrete FlowableEngineEventType constant (e.g. FlowableEngineEventType.PROCESS_STARTED).
- Validate/normalize the type lookup before constructing the event, falling back to a known default.
- Ensure custom dispatchers use ActivitiEventBuilder factory methods which never pass null types.
Example fix
// before FlowableEngineEventType type = TYPE_MAP.get(eventName); new ActivitiEventImpl(type, execId, procId, defId); // type may be null // after FlowableEngineEventType type = TYPE_MAP.getOrDefault(eventName, FlowableEngineEventType.CUSTOM); new ActivitiEventImpl(type, execId, procId, defId);
Defensive patterns
Strategy: validation
Validate before calling
if (type == null) type = FlowableEngineEventType.CUSTOM;
Type guard
FlowableEngineEventType safeType(FlowableEngineEventType t) { return t != null ? t : FlowableEngineEventType.CUSTOM; } Try / catch
try { dispatcher.dispatchEvent(new ActivitiEventImpl(type, e1, e2, e3)); } catch (ActivitiIllegalArgumentException e) { logger.error("Event type null", e); } Prevention
- Use ActivitiEventBuilder instead of constructing events directly
- Make type lookups total (getOrDefault with a known constant)
- Never map event names to types with functions that can return null
When it happens
Trigger: new ActivitiEventImpl(null, executionId, processInstanceId, processDefinitionId) or a subclass/builder call passing a null FlowableEngineEventType (e.g. a computed type variable that resolved to null).
Common situations: Custom listeners building events with a type looked up from a map or switch that returned null; mapping unknown event names to types; hand-written event constructors in tests.
Related errors
- Entity cannot be null.
- Entity cannot be null.
- Must specify a case definition id to migrate
- Must specify a case instance migration document to migrate
- Must specify a case instance id to migrate
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/42c24c505dbfb268.
Report an issue: GitHub.