flowable/flowable-engine · error · ActivitiIllegalArgumentException

keyLike is null

Error message

keyLike is null

What it means

ProcessDefinitionQueryImpl.processDefinitionKeyLike(String) throws ActivitiIllegalArgumentException 'keyLike is null' when the LIKE pattern is null. Like its siblings, the query builder validates the pattern eagerly to keep the generated SQL predicate valid. A null pattern is a caller contract violation, not a runtime query failure.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessDefinitionQueryImpl.java:168

            throw new ActivitiIllegalArgumentException("ids are null");
        }
        this.deploymentIds = deploymentIds;
        return this;
    }

    @Override
    public ProcessDefinitionQueryImpl processDefinitionKey(String key) {
        if (key == null) {
            throw new ActivitiIllegalArgumentException("key is null");
        }
        this.key = key;
        return this;
    }

    @Override
    public ProcessDefinitionQueryImpl processDefinitionKeyLike(String keyLike) {
        if (keyLike == null) {
            throw new ActivitiIllegalArgumentException("keyLike is null");
        }
        this.keyLike = keyLike;
        return this;
    }

    @Override
    public ProcessDefinitionQueryImpl processDefinitionResourceName(String resourceName) {
        if (resourceName == null) {
            throw new ActivitiIllegalArgumentException("resourceName is null");
        }
        this.resourceName = resourceName;
        return this;
    }

    @Override
    public ProcessDefinitionQueryImpl processDefinitionResourceNameLike(String resourceNameLike) {
        if (resourceNameLike == null) {
            throw new ActivitiIllegalArgumentException("resourceNameLike is null");

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Supply a non-null LIKE pattern such as "%invoice%"
  2. Only call processDefinitionKeyLike when the pattern is non-null; otherwise skip the filter
  3. Use "%" as a match-all default if that matches the intended semantics
  4. Catch ActivitiIllegalArgumentException to convert it into a 400-style client error

Example fix

// before
query.processDefinitionKeyLike(searchForm.getKeyPattern());
// after
if (searchForm.getKeyPattern() != null) {
    query.processDefinitionKeyLike(searchForm.getKeyPattern());
}
Defensive patterns

Strategy: validation

Validate before calling

if (keyLike == null) throw new IllegalArgumentException("keyLike pattern is required");
query.processDefinitionKeyLike(keyLike);

Type guard

boolean isValidPattern(String s) { return s != null && !s.isEmpty(); }

Try / catch

try {
    query.processDefinitionKeyLike(keyLike);
} catch (ActivitiIllegalArgumentException e) {
    if (e.getMessage().contains("keyLike is null")) {
        throw new BadRequestException("keyLike pattern must not be null");
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling ProcessDefinitionQuery.processDefinitionKeyLike(null), typically when the pattern comes from an optional request parameter or config value that is absent.

Common situations: Search UIs forwarding empty/absent pattern inputs; naming-convention filters configured via properties that are missing in one environment; refactors removing a default pattern constant.

Related errors


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