flowable/flowable-engine · error · IllegalStateException

Provided process definition must have both key and resource

Error message

Provided process definition must have both key and resource name set.

What it means

ProcessDefinitionDiagramHelper.createDiagramForProcessDefinition generates the PNG diagram resource for a deployed process definition, and requires both the definition's key and resourceName to be set to locate/build the artifact. If either is empty it fails fast with this IllegalStateException.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/deployer/ProcessDefinitionDiagramHelper.java:42

import org.slf4j.LoggerFactory;

/**
 * Creates diagrams from process definitions.
 */
public class ProcessDefinitionDiagramHelper {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProcessDefinitionDiagramHelper.class);

    /**
     * Generates a diagram resource for a ProcessDefinitionEntity and associated BpmnParse. The returned resource has not yet been persisted, nor attached to the ProcessDefinitionEntity. This requires
     * that the ProcessDefinitionEntity have its key and resource name already set.
     * 
     * The caller must determine whether creating a diagram for this process definition is appropriate or not, for example see {@link #shouldCreateDiagram(ProcessDefinitionEntity, DeploymentEntity)}.
     */
    public ResourceEntity createDiagramForProcessDefinition(ProcessDefinitionEntity processDefinition, BpmnParse bpmnParse) {

        if (StringUtils.isEmpty(processDefinition.getKey()) || StringUtils.isEmpty(processDefinition.getResourceName())) {
            throw new IllegalStateException("Provided process definition must have both key and resource name set.");
        }

        ResourceEntity resource = createResourceEntity();
        ProcessEngineConfiguration processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
        try {
            byte[] diagramBytes = IoUtil.readInputStream(
                    processEngineConfiguration.getProcessDiagramGenerator().generateDiagram(bpmnParse.getBpmnModel(), "png",
                            processEngineConfiguration.getActivityFontName(),
                            processEngineConfiguration.getLabelFontName(),
                            processEngineConfiguration.getAnnotationFontName(),
                            processEngineConfiguration.getClassLoader(),processEngineConfiguration.isDrawSequenceFlowNameWithNoLabelDI()),
                    null);
            String diagramResourceName = ResourceNameUtil.getProcessDiagramResourceName(
                    processDefinition.getResourceName(), processDefinition.getKey(), "png");

            resource.setName(diagramResourceName);
            resource.setBytes(diagramBytes);
            resource.setDeploymentId(processDefinition.getDeploymentId());

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure the BPMN parse step sets both key (process id) and resourceName before diagram creation
  2. Do not bypass the standard BpmnDeployer/Persister pipeline with custom deployer code
  3. If creating diagrams manually, populate key and resourceName on the entity first
  4. Verify shouldCreateDiagram gating in custom code matches the definition's state

Example fix

// before
ProcessDefinitionEntity def = ...; // resourceName never set
helper.createDiagramForProcessDefinition(def, bpmnParse);

// after
def.setResourceName("processes/order.bpmn20.xml");
helper.createDiagramForProcessDefinition(def, bpmnParse);
Defensive patterns

Strategy: validation

Validate before calling

if (StringUtils.isEmpty(processDefinition.getKey()) || StringUtils.isEmpty(processDefinition.getResourceName())) {
    return null; // skip diagram creation
}

Prevention

When it happens

Trigger: The diagram-generation deployer step runs (shouldCreateDiagram returned true) for a ProcessDefinitionEntity whose key or resourceName is empty — typically a programmatically constructed or partially initialized definition.

Common situations: Custom deployers bypassing the normal BpmnDeployer pipeline; definitions built in tests without a resourceName; lifecycle code calling the helper before parsing assigned the resource name.

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/c3c230c5b8cbd2a6. Report an issue: GitHub.