flowable/flowable-engine · error · FlowableException

deployment ' ' didn't put decision ' ' in the cache

Error message

deployment '${deploymentId}' didn't put decision '${decisionId}' in the cache

What it means

resolveDecision re-deploys the owning deployment so the decision lands in the decision cache; if after re-deployment getDecisionCacheEntry(decisionId) is still null, it throws FlowableException("deployment ... didn't put decision ... in the cache"). This is an internal invariant violation: the deployment exists but doesn't contain the referenced decision.

Solutions

  1. Redeploy the DMN resources cleanly: delete the broken deployment and deploy the .dmn files again.
  2. Check data integrity between ACT_DMN_DEPLOYMENT and ACT_DMN_DECISION for the given deploymentId/decisionId.
  3. Clear/invalidate the decision cache and restart the engine if stale cache entries are suspected.

Example fix

// before
// engine throws: deployment '12' didn't put decision '99' in the cache
// after
dmnRepositoryService.deleteDeployment("12");
dmnRepositoryService.createDeployment().addClasspathResource("approveOrder.dmn").deploy();
DecisionEntity d = manager.findDeployedDecisionById(validDecisionId);
Defensive patterns

Strategy: try-catch

Validate before calling

boolean consistent = dmnRepositoryService.createDeploymentQuery().deploymentId(deploymentId).count() > 0
    && dmnRepositoryService.createDecisionQuery().decisionId(decisionId).count() > 0;

Try / catch

try { return manager.findDeployedDecisionById(decisionId); } catch (FlowableException e) { if (e.getMessage() != null && e.getMessage().contains("didn't put decision")) { redeployBrokenDeployment(deploymentId); return manager.findDeployedDecisionById(decisionId); } throw e; }

Prevention

When it happens

Trigger: Reached from any findDeployed* lookup when a cached miss triggers re-resolution and the re-deployed deployment has no cache entry for the given decisionId — i.e. the deployment metadata references a decision it doesn't actually contain.

Common situations: Corrupted or partially-deleted deployment data (decision row deleted while deployment remains); manual database edits to ACT_DMN_ tables; upgrading Flowable across versions with stale cache/data.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/persistence/deploy/DeploymentManager.java:156

    public DecisionCacheEntry resolveDecision(DmnDecision decision) {
        String decisionId = decision.getId();
        String deploymentId = decision.getDeploymentId();

        DecisionCacheEntry cachedDecision = decisionCache.get(decisionId);

        if (cachedDecision == null) {
            DmnDeploymentEntity deployment = engineConfig.getDeploymentEntityManager().findById(deploymentId);
            List<DmnResourceEntity> resources = engineConfig.getResourceEntityManager().findResourcesByDeploymentId(deploymentId);
            for (DmnResourceEntity resource : resources) {
                deployment.addResource(resource);
            }

            deployment.setNew(false);
            deploy(deployment, null);
            cachedDecision = deployment.getDecisionCacheEntry(decisionId);

            if (cachedDecision == null) {
                throw new FlowableException("deployment '" + deploymentId + "' didn't put decision '" + decisionId + "' in the cache");
            }
        }
        return cachedDecision;
    }

    public void removeDeployment(String deploymentId) {

        DmnDeploymentEntity deployment = deploymentEntityManager.findById(deploymentId);
        if (deployment == null) {
            throw new FlowableObjectNotFoundException("Could not find a deployment with id '" + deploymentId + "'.");
        }

        // Remove any dmn definition from the cache
        List<DmnDecision> definitions = new DecisionQueryImpl().deploymentId(deploymentId).list();

        // Delete data
        deploymentEntityManager.deleteDeployment(deploymentId);

View on GitHub (pinned to d6d39ce1c6)