flowable/flowable-engine · error · FlowableIllegalArgumentException
Invalid action: ' '.
Error message
Invalid action: '${action}'. What it means
performPlanItemInstanceAction dispatches on the action string of a RestActionRequest (e.g. complete, enable, disable, start). Any action string outside the recognized set falls into the else branch and throws FlowableIllegalArgumentException, since no corresponding engine operation exists.
Solutions
- Use exactly one of the supported action strings handled by the method: complete, enable, disable, start (as matched via RestActionRequest constants).
- Compare against RestActionRequest constants or the REST documentation rather than free-form strings.
- Validate the action string client-side before POSTing.
- Catch FlowableIllegalArgumentException (HTTP 400) and show the allowed actions to the user.
Example fix
// before
{"action":"Complete"}
// after
{"action":"complete"} Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = ['complete','enable','disable','start'];
if (!ALLOWED.includes(action)) throw new Error(`Invalid action: ${action}`); Type guard
const isValidAction = (a) => ['complete','enable','disable','start'].includes(a);
Try / catch
try { await performAction(id, action); } catch (e) { if (e.status === 400 && /Invalid action/.test(e.message)) { /* show allowed actions */ } else { throw e; } } Prevention
- Use RestActionRequest constants, never raw literals
- Normalize action input (trim/lowercase) before sending
- Check per-resource action support in the REST docs
When it happens
Trigger: POST .../cmmn-runtime/plan-item-instances/{id}/action with body {"action":"..."} where the action is misspelled, in the wrong case, or not supported for this resource (e.g. 'complete' where not handled, 'trigger', 'resolve').
Common situations: Typos or casing mismatches in the action string; reusing action names valid on other Flowable REST resources (tasks/jobs); older client SDK sending actions removed in this version.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- No deployment id provided
- No resource name provided
- Only one of 'orderAscendingColumn' or…
- Only one of 'timersOnly' or 'messagesOnly' can be provided.
- A group or a user is required to create an identity link.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/c3a0cc4deaa6d43d.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/planitem/PlanItemInstanceResource.java:82
if (restApiInterceptor != null) {
restApiInterceptor.doPlanItemInstanceAction(planItemInstance, actionRequest);
}
if (RestActionRequest.TRIGGER.equals(actionRequest.getAction())) {
runtimeService.triggerPlanItemInstance(planItemInstance.getId());
} else if (RestActionRequest.ENABLE.equals(actionRequest.getAction())) {
runtimeService.startPlanItemInstance(planItemInstanceId);
} else if (RestActionRequest.DISABLE.equals(actionRequest.getAction())) {
runtimeService.disablePlanItemInstance(planItemInstanceId);
} else if (RestActionRequest.START.equals(actionRequest.getAction())) {
runtimeService.startPlanItemInstance(planItemInstanceId);
} else {
throw new FlowableIllegalArgumentException("Invalid action: '" + actionRequest.getAction() + "'.");
}
// Re-fetch the execution, could have changed due to action or even completed
planItemInstance = runtimeService.createPlanItemInstanceQuery().planItemInstanceId(planItemInstance.getId()).singleResult();
if (planItemInstance == null) {
// Execution is finished, return empty body to inform user
response.setStatus(HttpStatus.NO_CONTENT.value());
return null;
} else {
return restResponseFactory.createPlanItemInstanceResponse(planItemInstance);
}
}
}
View on GitHub (pinned to d6d39ce1c6)