flowable/flowable-engine · error · FlowableIllegalArgumentException

activityId is null

Error message

activityId is null

What it means

HistoricDecisionExecutionQueryImpl.activityId(String) throws FlowableIllegalArgumentException when the activityId argument is null. The activity id (the BPMN element that invoked the decision) is used as a direct database filter, so the builder throws FlowableIllegalArgumentException for null input.

Source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/HistoricDecisionExecutionQueryImpl.java:126

            throw new FlowableIllegalArgumentException("instanceId is null");
        }
        this.instanceId = instanceId;
        return this;
    }
    
    @Override
    public DmnHistoricDecisionExecutionQuery executionId(String executionId) {
        if (executionId == null) {
            throw new FlowableIllegalArgumentException("executionId is null");
        }
        this.executionId = executionId;
        return this;
    }
    
    @Override
    public DmnHistoricDecisionExecutionQuery activityId(String activityId) {
        if (activityId == null) {
            throw new FlowableIllegalArgumentException("activityId is null");
        }
        this.activityId = activityId;
        return this;
    }
    
    @Override
    public DmnHistoricDecisionExecutionQuery scopeType(String scopeType) {
        if (scopeType == null) {
            throw new FlowableIllegalArgumentException("scopeType is null");
        }
        this.scopeType = scopeType;
        return this;
    }
    
    @Override
    public DmnHistoricDecisionExecutionQuery withoutScopeType() {
        this.withoutScopeType = true;
        return this;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass the BPMN activity id that invokes the decision task, obtained from the delegate/execution context
  2. Apply activityId(...) conditionally only when a valid id exists; otherwise filter by other criteria
  3. Validate that the decision is actually invoked from a flow activity before using this filter

Example fix

// before
query.activityId(delegateExecution.getCurrentActivityId()); // may be null
// after
String activityId = delegateExecution != null
    ? delegateExecution.getCurrentActivityId() : null;
if (activityId != null) {
    query.activityId(activityId);
}
Defensive patterns

Strategy: validation

Validate before calling

if (activityId == null) { throw new IllegalArgumentException("activityId must be resolved from the invoking BPMN element"); }

Type guard

boolean hasActivityId(DelegateExecution ex) { return ex != null && ex.getCurrentActivityId() != null; }

Try / catch

try { query.activityId(actId); } catch (FlowableIllegalArgumentException e) { log.debug("activityId filter not applied (non-activity invocation)"); }

Prevention

When it happens

Trigger: Calling dmnHistoryService.createHistoricDecisionExecutionQuery().activityId(null), usually when the current flow element is resolved from an execution context that is empty or when the caller passes an optional activity filter that was never set.

Common situations: Per-activity decision audit reports where the invoking activity id is unknown (e.g. decision called via API, not from a BPMN activity); request-driven filters with absent parameters; process refactors that removed the calling activity.

Related errors


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