flowable/flowable-engine · error · FlowableIllegalArgumentException

executionId is null

Error message

executionId is null

What it means

GetDataObjectCmd reads a named DataObject for an execution. Its first validation is that executionId must be non-null; a null id throws FlowableIllegalArgumentException before any database lookup. This is an input-validation failure, not a lookup miss.

Solutions

  1. Guarantee a non-null executionId before invoking the data-object API
  2. Obtain the id from ExecutionEntity.getId() of a freshly fetched execution
  3. If execution context is unavailable, resolve it via runtimeService.createExecutionQuery() on the process instance id
  4. Treat this as a programming bug: log and fail fast upstream where the id is produced

Example fix

// before
DataObject d = runtimeService.getDataObject(executionId, "objectName"); // executionId may be null
// after
if (executionId != null) {
    DataObject d = runtimeService.getDataObject(executionId, "objectName");
}
Defensive patterns

Strategy: validation

Validate before calling

if (executionId == null || executionId.isEmpty()) return null;
DataObject d = runtimeService.getDataObject(executionId, name);

Type guard

boolean hasExecutionId(String id) { return id != null && !id.isEmpty(); }

Prevention

When it happens

Trigger: Calling runtimeService.getDataObject(null, dataObjectName) or getDataObjectLocal with a null execution id; an Execution entity obtained from a query returned and its id was not stored; variables maps built dynamically with missing execution references.

Common situations: Asynchronous listeners running after the execution was handled; passing an optional variable that was never initialized; scripting/template expressions evaluating to null.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/b9a3668885b1a494. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetDataObjectCmd.java:65

    public GetDataObjectCmd(String executionId, String dataObjectName, boolean isLocal) {
        this.executionId = executionId;
        this.dataObjectName = dataObjectName;
        this.isLocal = isLocal;
    }

    public GetDataObjectCmd(String executionId, String dataObjectName, boolean isLocal, String locale, boolean withLocalizationFallback) {
        this.executionId = executionId;
        this.dataObjectName = dataObjectName;
        this.isLocal = isLocal;
        this.locale = locale;
        this.withLocalizationFallback = withLocalizationFallback;
    }

    @Override
    public DataObject execute(CommandContext commandContext) {
        if (executionId == null) {
            throw new FlowableIllegalArgumentException("executionId is null");
        }
        if (dataObjectName == null) {
            throw new FlowableIllegalArgumentException("dataObjectName is null");
        }

        ExecutionEntity execution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(executionId);

        if (execution == null) {
            throw new FlowableObjectNotFoundException("execution " + executionId + " doesn't exist", Execution.class);
        }

        DataObject dataObject = null;

        VariableInstance variableEntity = null;
        if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, execution.getProcessDefinitionId())) {
            Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler();
            variableEntity = compatibilityHandler.getExecutionVariableInstance(executionId, dataObjectName, isLocal);

View on GitHub (pinned to d6d39ce1c6)