flowable/flowable-engine · error · FlowableIllegalArgumentException

Message name is required

Error message

Message name is required

What it means

FlowableIllegalArgumentException thrown by ExecutionResource.performExecutionAction when the action is 'message-event-received' but messageName is null. Delivering a message to an execution requires the message name to match the message-catching event in the process definition.

Solutions

  1. Add "messageName" to the request body with the exact message name from the BPMN model.
  2. Check the JSON key is 'messageName', not 'signalName' (a signal payload is rejected here).
  3. Confirm the execution is waiting at a message boundary/intermediate catch event with that message name.
  4. Match the message name exactly as declared in the process definition (case-sensitive).

Example fix

// before
{"action": "message-event-received", "signalName": "paymentReceived"}
// after
{"action": "message-event-received", "messageName": "paymentReceived"}
Defensive patterns

Strategy: validation

Validate before calling

if (body.action === 'message-event-received' && (!body.messageName || typeof body.messageName !== 'string')) {
  throw new Error(`POST /runtime/executions/${executionId} requires "messageName" for action message-event-received`);
}

Type guard

function isMessageRequest(b: { action?: string; messageName?: unknown }): b is { action: 'message-event-received'; messageName: string } {
  return b.action === 'message-event-received' && typeof b.messageName === 'string' && b.messageName.length > 0;
}

Try / catch

try {
  await restClient.post(`/runtime/executions/${executionId}`, body);
} catch (e) {
  if (e.response && e.response.status === 400 && /Message name is required/.test(e.response.data && e.response.data.message || '')) {
    console.error('Add "messageName" to the execution action request body');
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /runtime/executions/{executionId} with body {"action":"message-event-received"} and no (or null) messageName field, e.g. when the client reuses a signal-style payload that only sets signalName.

Common situations: Copy-pasting signal payloads and forgetting to swap signalName for messageName; message name empty in external system integration config; key misspelled as 'message' or '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/73fd0b169fc37f78. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ExecutionResource.java:89

            } else if (actionRequest.getVariables() != null) {
                runtimeService.trigger(execution.getId(), getVariablesToSet(actionRequest.getVariables()));
            } else {
                runtimeService.trigger(execution.getId());
            }
            
        } else if (ExecutionActionRequest.ACTION_SIGNAL_EVENT_RECEIVED.equals(actionRequest.getAction())) {
            if (actionRequest.getSignalName() == null) {
                throw new FlowableIllegalArgumentException("Signal name is required");
            }
            if (actionRequest.getVariables() != null) {
                runtimeService.signalEventReceived(actionRequest.getSignalName(), execution.getId(), getVariablesToSet(actionRequest.getVariables()));
            } else {
                runtimeService.signalEventReceived(actionRequest.getSignalName(), execution.getId());
            }
            
        } else if (ExecutionActionRequest.ACTION_MESSAGE_EVENT_RECEIVED.equals(actionRequest.getAction())) {
            if (actionRequest.getMessageName() == null) {
                throw new FlowableIllegalArgumentException("Message name is required");
            }
            if (actionRequest.getVariables() != null) {
                runtimeService.messageEventReceived(actionRequest.getMessageName(), execution.getId(), getVariablesToSet(actionRequest.getVariables()));
            } else {
                runtimeService.messageEventReceived(actionRequest.getMessageName(), execution.getId());
            }
            
        } else {
            throw new FlowableIllegalArgumentException("Invalid action: '" + actionRequest.getAction() + "'.");
        }

        // Re-fetch the execution, could have changed due to action or even completed
        execution = runtimeService.createExecutionQuery().executionId(execution.getId()).singleResult();
        if (execution == null) {
            // Execution is finished, return empty body to inform user
            response.setStatus(HttpStatus.NO_CONTENT.value());
            return null;
        } else {

View on GitHub (pinned to d6d39ce1c6)