flowable/flowable-engine · error · FlowableIllegalArgumentException

decisionKey is null

Error message

decisionKey is null

What it means

ExecuteDecisionServiceCmd performs the same null-key guard as ExecuteDecisionCmd, but for decision service invocations: it throws FlowableIllegalArgumentException when executeDecisionContext.getDecisionKey() is null. The decision key here identifies the decision service element inside the deployed DMN definition, and it is required before definition resolution can proceed.

Source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/cmd/ExecuteDecisionServiceCmd.java:61

    public ExecuteDecisionServiceCmd(String decisionKey, String parentDeploymentId, Map<String, Object> variables) {
        this(decisionKey, variables);
        executeDecisionContext.setParentDeploymentId(parentDeploymentId);
    }

    public ExecuteDecisionServiceCmd(String decisionKey, String parentDeploymentId, Map<String, Object> variables, String tenantId) {
        this(decisionKey, parentDeploymentId, variables);
        executeDecisionContext.setTenantId(tenantId);
    }

    public ExecuteDecisionServiceCmd(ExecuteDecisionContext executeDecisionContext) {
        super(executeDecisionContext);
    }

    @Override
    public Void execute(CommandContext commandContext) {
        if (executeDecisionContext.getDecisionKey() == null) {
            throw new FlowableIllegalArgumentException("decisionKey is null");
        }

        DmnDefinition definition = resolveDefinition();

        execute(commandContext, definition);

        return null;
    }

    @Override
    protected void execute(CommandContext commandContext, DmnDefinition definition) {
        DecisionService decisionService = definition.getDecisionServiceById(executeDecisionContext.getDecisionKey());

        if (decisionService == null) {
            throw new FlowableIllegalArgumentException("no decision service with id: '" + executeDecisionContext.getDecisionKey() + "' found in definition");
        }

        executeDecisionContext.setDmnElement(decisionService);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass a non-null decision service key: getDmnDecisionService().executeDecisionService("myDecisionService", variables)
  2. Trim/fail fast on the caller side when the incoming key is null or blank
  3. Confirm the builder chain ends with .decisionServiceKey(...) / decisionKey(...) being invoked before execute

Example fix

// before
decisionService.executeDecisionService(request.getKey(), vars);
// after
String key = request.getKey();
Objects.requireNonNull(key, "decision service key is required");
decisionService.executeDecisionService(key, vars);
Defensive patterns

Strategy: validation

Validate before calling

if (serviceKey == null || serviceKey.isBlank()) throw new IllegalArgumentException("decision service key is required");

Try / catch

try { decisionService.executeDecisionService(key, vars); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().equals("decisionKey is null")) { return badRequest("decision service key missing"); } throw e; }

Prevention

When it happens

Trigger: Calling DmnDecisionService.executeDecisionService(...) or executeDecisionServiceWithVariables(...) with a null key, or building an ExecuteDecisionContext without setting the key.

Common situations: Key passed in from an upstream service result that is null; REST/API layer dropping the key parameter; decision service key stored in a config map keyed incorrectly so lookup returns null.

Related errors


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