flowable/flowable-engine · error · FlowableIllegalArgumentException

Provided decision must have a deployment id.

Error message

Provided decision must have a deployment id.

What it means

DmnDeploymentHelper.getPersistedInstanceOfDecision requires the incoming DecisionEntity to already carry a deploymentId, since it queries for the decision persisted under that specific deployment. An empty deploymentId triggers FlowableIllegalArgumentException before any entity-manager query runs.

Source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/deployer/DmnDeploymentHelper.java:108

        DecisionEntity existingDecision;

        if (tenantId != null && !tenantId.equals(DmnEngineConfiguration.NO_TENANT_ID)) {
            existingDecision = decisionTableEntityManager.findLatestDecisionByKeyAndTenantId(key, tenantId);
        } else {
            existingDecision = decisionTableEntityManager.findLatestDecisionByKey(key);
        }

        return existingDecision;
    }

    /**
     * Gets the persisted version of the already-deployed decision. Note that this is different from {@link #getMostRecentVersionOfDecision} as it looks specifically for a decision
     * that is already persisted and attached to a particular deployment, rather than the latest version across all deployments.
     */
    public DecisionEntity getPersistedInstanceOfDecision(DecisionEntity decision) {
        String deploymentId = decision.getDeploymentId();
        if (StringUtils.isEmpty(decision.getDeploymentId())) {
            throw new FlowableIllegalArgumentException("Provided decision must have a deployment id.");
        }

        DecisionEntityManager decisionEntityManager = CommandContextUtil.getDmnEngineConfiguration().getDecisionEntityManager();
        DecisionEntity persistedDecision;
        if (decision.getTenantId() == null || DmnEngineConfiguration.NO_TENANT_ID.equals(decision.getTenantId())) {
            persistedDecision = decisionEntityManager.findDecisionByDeploymentAndKey(deploymentId, decision.getKey());
        } else {
            persistedDecision = decisionEntityManager.findDecisionByDeploymentAndKeyAndTenantId(deploymentId, decision.getKey(), decision.getTenantId());
        }

        return persistedDecision;
    }

    /**
     * Creates new diagrams for decisions if the deployment is new, the decision in question supports it, and the engine is configured to make new diagrams.
     *
     * When this method creates a new diagram, it also persists it via the ResourceEntityManager and adds it to the resources of the deployment.
     */

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Set deploymentId on the decision before calling this method (decision.setDeploymentId(deployment.getId())).
  2. Ensure the built-in DeploymentIdDeployer/DmnDeployment stages run so the entity is populated during deployment.
  3. In tests, populate deploymentId (and key) on the fixture before invoking the helper.
  4. Use getMostRecentVersionOfDecision instead if you want version lookup by key, not per-deployment lookup.

Example fix

// before
DecisionEntity persisted = deploymentHelper.getPersistedInstanceOfDecision(newDecision);
// after
newDecision.setDeploymentId(deploymentEntity.getId());
DecisionEntity persisted = deploymentHelper.getPersistedInstanceOfDecision(newDecision);
Defensive patterns

Strategy: validation

Validate before calling

if (StringUtils.isEmpty(decision.getDeploymentId())) {
    throw new IllegalArgumentException("decision.deploymentId must be set before per-deployment lookup");
}

Try / catch

try {
    DecisionEntity persisted = helper.getPersistedInstanceOfDecision(decision);
} catch (FlowableIllegalArgumentException e) {
    // decision was not yet attached to a deployment
}

Prevention

When it happens

Trigger: Calling getPersistedInstanceOfDecision with a freshly built (not yet persisted) DecisionEntity whose deploymentId was never set — e.g. custom deployer code that constructs a decision instead of obtaining it from the deployment pipeline.

Common situations: Custom DmnDeployer implementations that reorder/replace the built-in deployers so the decision's deploymentId field isn't populated yet; unit tests building DecisionEntity objects manually; refactors that drop the setDeploymentId call.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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