{"record":{"id":"d9559e95a061f072","repo":"flowable/flowable-engine","slug":"the-decision-table-id-is-mandatory-but-decision","errorCode":null,"errorMessage":"The decision table id is mandatory, but '<decisionTableId>' has been provided.","messagePattern":"The decision table id is mandatory, but '<decisionTableId>' has been provided\\.","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/cmd/GetDeploymentDmnResourceCmd.java","lineNumber":37,"sourceCode":"import org.flowable.common.engine.api.FlowableIllegalArgumentException;\nimport org.flowable.common.engine.impl.interceptor.Command;\nimport org.flowable.common.engine.impl.interceptor.CommandContext;\nimport org.flowable.dmn.engine.impl.persistence.entity.DecisionEntity;\nimport org.flowable.dmn.engine.impl.util.CommandContextUtil;\n\n/**\n * Gives access to a deployed decision table model, e.g., a DMN XML file, through a stream of bytes.\n * \n * @author Tijs Rademakers\n */\npublic class GetDeploymentDmnResourceCmd implements Command<InputStream>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n    protected String decisionTableId;\n\n    public GetDeploymentDmnResourceCmd(String decisionTableId) {\n        if (decisionTableId == null || decisionTableId.length() < 1) {\n            throw new FlowableIllegalArgumentException(\"The decision table id is mandatory, but '\" + decisionTableId + \"' has been provided.\");\n        }\n        this.decisionTableId = decisionTableId;\n    }\n\n    @Override\n    public InputStream execute(CommandContext commandContext) {\n        DecisionEntity decisionTable = CommandContextUtil.getDmnEngineConfiguration().getDeploymentManager().findDeployedDecisionById(decisionTableId);\n        String deploymentId = decisionTable.getDeploymentId();\n        String resourceName = decisionTable.getResourceName();\n        InputStream processModelStream = new GetDeploymentResourceCmd(deploymentId, resourceName).execute(commandContext);\n        return processModelStream;\n    }\n\n}\n","sourceCodeStart":19,"sourceCodeEnd":52,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/cmd/GetDeploymentDmnResourceCmd.java#L19-L52","documentation":"GetDeploymentDmnResourceCmd's constructor requires a non-empty decision table id and throws FlowableIllegalArgumentException with the offending (blank) value otherwise. It is the same fail-fast pattern as the DRD diagram command, applied when fetching the raw DMN resource for a decision table.","triggerScenarios":"new GetDeploymentDmnResourceCmd(null) or length < 1 — e.g. dmnRepositoryService.getDecisionTableResource? or getDeploymentResource flow invoked with a null decisionTableId.","commonSituations":"Passing the id from an unset variable or empty optional; REST layer accepting blank path segments; migrating code from another engine API where empty ids were tolerated.","solutions":["Supply the decision table id from a real deployment: DmnDecisionTable.getId() from a repository query","Validate non-null/non-empty before constructing the command","If ids are generated client-side, ensure the generation step actually ran (check for empty string rather than just null)"],"exampleFix":"// before\nnew GetDeploymentDmnResourceCmd(tableIdOrEmpty); // may be \"\"\n// after\nif (tableId == null || tableId.isEmpty()) {\n    throw new BadRequestException(\"decisionTableId is required\");\n}\nnew GetDeploymentDmnResourceCmd(tableId);","handlingStrategy":"validation","validationCode":"if (decisionTableId == null || decisionTableId.isEmpty()) throw new IllegalArgumentException(\"decision table id is required\");","typeGuard":null,"tryCatchPattern":"try { new GetDeploymentDmnResourceCmd(id); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().startsWith(\"The decision table id is mandatory\")) { throw new BadRequestException(\"decisionTableId required\"); } throw e; }","preventionTips":["Obtain ids from DmnDecisionTable entities returned by queries","Treat blank strings as invalid everywhere, not just null","Add bean validation on DTOs carrying ids"],"tags":["flowable","dmn","empty-required-field","api-misuse"],"backgroundTag":"empty-required-field","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}