flowable/flowable-engine · error · FlowableIllegalArgumentException

Invalid usage: cannot use deployed() and notDeployed() in th

Error message

Invalid usage: cannot use deployed() and notDeployed() in the same query

What it means

ModelQueryImpl.notDeployed() marks the query as filtering for models not yet deployed, but deployed() and notDeployed() are mutually exclusive filters. If deployed() was already called on the same query, notDeployed() throws FlowableIllegalArgumentException to prevent a contradictory WHERE condition. This is a fail-fast guard against an impossible query.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ModelQueryImpl.java:149

    @Override
    public ModelQuery latestVersion() {
        this.latest = true;
        return this;
    }

    @Override
    public ModelQuery deploymentId(String deploymentId) {
        if (deploymentId == null) {
            throw new FlowableIllegalArgumentException("DeploymentId is null");
        }
        this.deploymentId = deploymentId;
        return this;
    }

    @Override
    public ModelQuery notDeployed() {
        if (deployed) {
            throw new FlowableIllegalArgumentException("Invalid usage: cannot use deployed() and notDeployed() in the same query");
        }
        this.notDeployed = true;
        return this;
    }

    @Override
    public ModelQuery deployed() {
        if (notDeployed) {
            throw new FlowableIllegalArgumentException("Invalid usage: cannot use deployed() and notDeployed() in the same query");
        }
        this.deployed = true;
        return this;
    }

    @Override
    public ModelQuery modelTenantId(String tenantId) {
        if (tenantId == null) {
            throw new FlowableIllegalArgumentException("Model tenant id is null");

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Use only one of deployed() or notDeployed() per query instance.
  2. If the choice is dynamic, branch: if (onlyDeployed) q.deployed(); else if (onlyNotDeployed) q.notDeployed();
  3. Mutually exclude the flags at the input/validation layer so both can never be true.
  4. Create a fresh ModelQuery instead of reusing one that already has a deployment filter applied.

Example fix

// before
ModelQuery query = repositoryService.createModelQuery()
    .deployed()
    .notDeployed(); // contradiction

// after
ModelQuery query = repositoryService.createModelQuery();
if (deployedOnly) {
    query.deployed();
} else {
    query.notDeployed();
}
Defensive patterns

Strategy: validation

Validate before calling

if (onlyDeployed && onlyNotDeployed) {
    throw new IllegalArgumentException("Choose either deployed or notDeployed filter, not both");
}
ModelQuery q = repositoryService.createModelQuery();
if (onlyDeployed) q.deployed(); else if (onlyNotDeployed) q.notDeployed();

Try / catch

try {
    return queryBuilder.applyDeploymentFilter(flags).list();
} catch (FlowableIllegalArgumentException e) {
    log.warn("Conflicting deployment filters: {}", e.getMessage());
    throw new BadRequestException("deployed and notDeployed cannot be combined");
}

Prevention

When it happens

Trigger: Calling both deployed() and notDeployed() on the same ModelQuery instance, e.g. building the filter dynamically from flags where both booleans end up true (user selected both options in a UI, or two code paths each add one filter).

Common situations: Dynamic query builders in REST/admin UIs mapping checkbox states straight to query calls; refactored code where a shared query object is reused and one method already applied deployed(); copying example code that had deployed() and adding notDeployed().

Related errors


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