flowable/flowable-engine · error · ActivitiIllegalArgumentException

Invalid query usage: cannot set both taskNameInIgnoreCase…

Error message

Invalid query usage: cannot set both taskNameInIgnoreCase and nameLike

What it means

taskNameInIgnoreCase is mutually exclusive with the pattern filter taskNameLike. Setting both makes the name criterion ambiguous, so the setter throws ActivitiIllegalArgumentException when taskNameLike is already non-null.

Solutions

  1. Pick one strategy: remove the taskNameLike call, or keep only taskNameLike.
  2. For case-insensitive matching of exact values, taskNameInIgnoreCase alone already covers the use case that taskNameLike was approximating.
  3. Build the query from scratch per request rather than mutating a shared instance.

Example fix

// before
query.taskNameLike("%rev%");
query.taskNameInIgnoreCase(names);
// after
query.taskNameInIgnoreCase(names); // drop the LIKE filter
Defensive patterns

Strategy: validation

Validate before calling

if (pattern != null) {
    query.taskNameLike(pattern);
} else if (names != null && !names.isEmpty()) {
    query.taskNameInIgnoreCase(names);
}

Type guard

boolean canUseTaskNameInIgnoreCase(HistoricTaskInstanceQueryImpl q) { return q.getTaskNameLike() == null; }

Try / catch

try {
    query.taskNameInIgnoreCase(names);
} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {
    // taskNameLike already set — pick one strategy and rebuild
    throw new IllegalArgumentException("Use either taskNameLike or taskNameInIgnoreCase", e);
}

Prevention

When it happens

Trigger: Calling .taskNameInIgnoreCase(List<String>) after .taskNameLike("%rev%") on the same query instance.

Common situations: Search UIs that offer both 'contains' text input and multi-select exact names; code that applies a LIKE fallback then also an IN list.

Related errors


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/HistoricTaskInstanceQueryImpl.java:420

    @Override
    public HistoricTaskInstanceQuery taskNameInIgnoreCase(List<String> taskNameList) {
        if (taskNameList == null) {
            throw new ActivitiIllegalArgumentException("Task name list is null");
        }
        if (taskNameList.isEmpty()) {
            throw new ActivitiIllegalArgumentException("Task name list is empty");
        }
        for (String taskName : taskNameList) {
            if (taskName == null) {
                throw new ActivitiIllegalArgumentException("None of the given task names can be null");
            }
        }

        if (taskName != null) {
            throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both taskNameInIgnoreCase and name");
        }
        if (taskNameLike != null) {
            throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both taskNameInIgnoreCase and nameLike");
        }
        if (taskNameLikeIgnoreCase != null) {
            throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both taskNameInIgnoreCase and nameLikeIgnoreCase");
        }

        final int nameListSize = taskNameList.size();
        final List<String> caseIgnoredTaskNameList = new ArrayList<>(nameListSize);
        for (String taskName : taskNameList) {
            caseIgnoredTaskNameList.add(taskName.toLowerCase());
        }

        if (inOrStatement) {
            this.currentOrQueryObject.taskNameListIgnoreCase = caseIgnoredTaskNameList;
        } else {
            this.taskNameListIgnoreCase = caseIgnoredTaskNameList;
        }
        return this;
    }

View on GitHub (pinned to d6d39ce1c6)