flowable/flowable-engine · error · FlowableIllegalArgumentException
Signal name is required
Error message
Signal name is required
What it means
FlowableIllegalArgumentException thrown by ExecutionResource.performExecutionAction when the action is 'signal-event-received' but signalName is null. This per-execution endpoint delivers a signal to a specific execution waiting at a signal-catching event; the signal name identifies which event to fire.
Solutions
- Add "signalName" to the request body with the exact signal name from the BPMN model.
- Verify the JSON key spelling/casing is 'signalName'.
- If you meant to just continue a waiting execution without an event, use action "trigger" instead (no signalName needed).
- Ensure the execution is actually waiting at a signal-catching event with that name, otherwise the next call will fail with a different error.
Example fix
// before
{"action": "signal-event-received"}
// after
{"action": "signal-event-received", "signalName": "paymentReceived"} Defensive patterns
Strategy: validation
Validate before calling
if (body.action === 'signal-event-received' && (!body.signalName || typeof body.signalName !== 'string')) {
throw new Error(`POST /runtime/executions/${executionId} requires "signalName" for action signal-event-received`);
} Type guard
function isSignalRequest(b: { action?: string; signalName?: unknown }): b is { action: 'signal-event-received'; signalName: string } {
return b.action === 'signal-event-received' && typeof b.signalName === 'string' && b.signalName.length > 0;
} Try / catch
try {
await restClient.post(`/runtime/executions/${executionId}`, body);
} catch (e) {
if (e.response && e.response.status === 400 && /Signal name is required/.test(e.response.data && e.response.data.message || '')) {
console.error('Add "signalName" to the execution action request body');
}
throw e;
} Prevention
- Set signalName whenever action is 'signal-event-received' on the per-execution endpoint.
- Use action 'trigger' (no signalName) when you only want to continue the execution.
- Derive request bodies from typed client methods, not ad-hoc objects.
- Verify the target execution is waiting at the matching signal catch event.
When it happens
Trigger: POST /runtime/executions/{executionId} with body {"action":"signal-event-received"} and no (or null) signalName field.
Common situations: Clients migrating from the collection endpoint forgetting the payload shape; building the body dynamically where the signal name variable is null; typos like 'signal-name' in JSON keys.
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
- Signal name is required.
- A request body was expected when executing the form submit.
- Attachment name is required.
- Error converting request body to RestVariable instance
- Id cannot be null.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/91ef1762aa47aba4.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ExecutionResource.java:79
Execution execution = getExecutionFromRequest(executionId);
if (restApiInterceptor != null) {
restApiInterceptor.doExecutionActionRequest(execution, actionRequest);
}
if (ExecutionActionRequest.ACTION_SIGNAL.equals(actionRequest.getAction())
|| ExecutionActionRequest.ACTION_TRIGGER.equals(actionRequest.getAction())) {
if (actionRequest.getTransientVariables() != null && actionRequest.getVariables() != null) {
runtimeService.trigger(execution.getId(), getVariablesToSet(actionRequest.getVariables()), getVariablesToSet(actionRequest.getTransientVariables()));
} 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 {View on GitHub (pinned to d6d39ce1c6)