flowable/flowable-engine · error · FlowableIllegalArgumentException

Task parentScopeId is null

Error message

Task parentScopeId is null

What it means

taskRootScopeId(String) requires a non-null root scope id; passing null throws this FlowableIllegalArgumentException (the message says 'parentScopeId' but the method is taskRootScopeId). The library validates arguments eagerly so the query never executes with an unset filter value.

Solutions

  1. Check for null before calling taskRootScopeId and skip the filter when absent
  2. Ensure the root scope id is actually resolved (e.g. via runtimeService/historic process instance) before querying
  3. Use the correct method (taskParentScopeId) if a parent scope was intended

Example fix

// before
query.taskRootScopeId(rootScopeId); // may be null
// after
if (rootScopeId != null) { query.taskRootScopeId(rootScopeId); }
Defensive patterns

Strategy: validation

Validate before calling

if (rootScopeId != null) { query.taskRootScopeId(rootScopeId); }

Type guard

boolean hasRootScopeId(String id) { return id != null && !id.isBlank(); }

Try / catch

try {
    query.taskRootScopeId(rootScopeId);
} catch (FlowableIllegalArgumentException e) {
    // proceed without the scope filter or log and skip
}

Prevention

When it happens

Trigger: Calling taskRootScopeId(null) directly, or passing a variable/expression that resolves to null (e.g. process instance's root scope id not yet available).

Common situations: Dynamic query builders forwarding an optional scope-id parameter without a null check; copy-pasting the parentScopeId call into the rootScopeId slot.

Related errors


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

Appendix: source

Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskInstanceQueryImpl.java:1412

            this.scopedVariableExists(name, ScopeTypes.CMMN);
        }
        return this;
    }

    @Override
    public HistoricTaskInstanceQuery caseVariableNotExists(String name) {
        if (inOrStatement) {
            currentOrQueryObject.scopedVariableNotExists(name, ScopeTypes.CMMN);
        } else {
            this.scopedVariableNotExists(name, ScopeTypes.CMMN);
        }
        return this;
    }

    @Override
    public HistoricTaskInstanceQuery taskRootScopeId(String rootScopeId) {
        if (rootScopeId == null) {
            throw new FlowableIllegalArgumentException("Task parentScopeId is null");
        }
        if (inOrStatement) {
            currentOrQueryObject.rootScopeId = rootScopeId;
        } else {
            this.rootScopeId = rootScopeId;
        }
        return this;
    }

    @Override
    public HistoricTaskInstanceQuery taskParentScopeId(String parentScopeId) {
        if (parentScopeId == null) {
            throw new FlowableIllegalArgumentException("Task parentScopeId is null");
        }
        if (inOrStatement) {
            currentOrQueryObject.parentScopeId = parentScopeId;
        } else {
            this.parentScopeId = parentScopeId;

View on GitHub (pinned to d6d39ce1c6)