Activiti/Activiti · error · ActivitiIllegalArgumentException

Provided exception message is null

Error message

Provided exception message is null

What it means

JobQueryImpl.exceptionMessage(String) narrows the query to jobs whose last failure message matches the given text; a null message cannot be matched, so the engine throws ActivitiIllegalArgumentException when null is passed. To find jobs with any exception, use withException() instead of a null exception message.

Solutions

  1. Only call exceptionMessage() when a non-null, non-empty message string is available
  2. If you want any failed job regardless of message, call withException() instead of exceptionMessage(null)
  3. Treat empty search input as 'no filter' rather than passing null
  4. Trim and validate the message input at the UI/API layer before querying

Example fix

// before
List<Job> failed = managementService.createJobQuery()
    .withException()
    .exceptionMessage(search.getMessage())
    .list();
// after
JobQuery query = managementService.createJobQuery().withException();
if (search.getMessage() != null && !search.getMessage().isEmpty()) {
    query.exceptionMessage(search.getMessage());
}
List<Job> failed = query.list();
Defensive patterns

Strategy: validation

Validate before calling

// Java
if (message == null || message.isEmpty()) {
    throw new IllegalArgumentException("exceptionMessage requires a non-null string; use withException() for any failure");
}

Type guard

// Java
boolean hasExceptionFilter(JobSearch s) {
    return s.getMessage() != null && !s.getMessage().trim().isEmpty();
}

Try / catch

// Java
try {
    jobs = managementService.createJobQuery().withException().exceptionMessage(msg).list();
} catch (ActivitiIllegalArgumentException e) {
    if (e.getMessage().contains("exception message is null")) {
        jobs = managementService.createJobQuery().withException().list();
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling createJobQuery().exceptionMessage(null), e.g. when the message comes from a failed stack-trace/message lookup that returned null, or from an absent search field in an admin UI.

Common situations: Operations dashboards for failed jobs where the 'error contains' field is empty (null) and passed through, propagating the message from a caught exception that was itself null (NPE-free catch of a null getMessage()), or copying fields between job DTOs.

Related errors


AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09). Data as JSON: /api/errors/e18ff521fd479da2. Report an issue: GitHub.

Appendix: source

Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/JobQueryImpl.java:181

            throw new ActivitiIllegalArgumentException("Provided date is null");
        }
        this.duedateLowerThanOrEqual = date;
        return this;
    }

    public JobQuery noRetriesLeft() {
        noRetriesLeft = true;
        return this;
    }

    public JobQuery withException() {
        this.withException = true;
        return this;
    }

    public JobQuery exceptionMessage(String exceptionMessage) {
        if (exceptionMessage == null) {
            throw new ActivitiIllegalArgumentException("Provided exception message is null");
        }
        this.exceptionMessage = exceptionMessage;
        return this;
    }

    public JobQuery jobTenantId(String tenantId) {
        if (tenantId == null) {
            throw new ActivitiIllegalArgumentException("job is null");
        }
        this.tenantId = tenantId;
        return this;
    }

    public JobQuery jobTenantIdLike(String tenantIdLike) {
        if (tenantIdLike == null) {
            throw new ActivitiIllegalArgumentException("job is null");
        }
        this.tenantIdLike = tenantIdLike;

View on GitHub (pinned to 56435b1a97)