flowable/flowable-engine · error · FlowableIllegalArgumentException

Invalid action, only 'move' or 'reschedule' are supported.

Error message

Invalid action, only 'move' or 'reschedule' are supported.

What it means

The CMMN REST API timer-job action endpoint only supports the 'move' and 'reschedule' actions. Flowable throws FlowableIllegalArgumentException when the request body is missing or its 'action' field is anything else. It is a client-side request validation error, not an engine failure.

Solutions

  1. Set the request body's action field to exactly 'move' or 'reschedule'
  2. Ensure the JSON body is actually sent and deserialized (Content-Type: application/json, non-null body)
  3. Check API docs / Swagger for the endpoint's accepted actions before calling

Example fix

// before
curl -X POST /cmmn-management/timer-jobs/42 -d '{"action":"execute"}'
// after
curl -X POST /cmmn-management/timer-jobs/42 -d '{"action":"reschedule","dueDate":"2026-01-01T10:00:00Z"}'
Defensive patterns

Strategy: validation

Validate before calling

const allowed = ['move','reschedule'];
if (!body || !allowed.includes(body.action)) throw new Error("action must be 'move' or 'reschedule'");

Type guard

function isValidTimerAction(a) { return a === 'move' || a === 'reschedule'; }

Try / catch

try { await post(`/cmmn-management/timer-jobs/${id}`, body); }
catch (e) { if (e.status === 400 && /Invalid action/.test(e.message)) { /* fix action field */ } else throw e; }

Prevention

When it happens

Trigger: POST /cmmn-management/timer-jobs/{jobId} with a null/empty body, or with an action value other than exactly 'move' or 'reschedule' (e.g. 'execute', 'Move', 'retry').

Common situations: Copy-pasting request payloads from the BPMN REST API or deadletter-job endpoint (which use different action names), case mismatches, or omitting the JSON body entirely.

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


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

Appendix: source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/management/JobResource.java:243

        try {
            managementService.executeJob(job.getId());
        } catch (FlowableObjectNotFoundException e) {
            // Re-throw to have consistent error-messaging across REST-api
            throw new FlowableObjectNotFoundException("Could not find a job with id '" + jobId + "'.", Job.class);
        }
    }

    @ApiOperation(value = "Execute a single job action (move or reschedule)", tags = { "Jobs" }, code = 204)
    @ApiResponses(value = {
            @ApiResponse(code = 204, message = "Indicates the timer job action was executed. Response-body is intentionally empty."),
            @ApiResponse(code = 404, message = "Indicates the requested job was not found."),
            @ApiResponse(code = 500, message = "Indicates the an exception occurred while executing the job. The status-description contains additional detail about the error. The full error-stacktrace can be fetched later on if needed.")
    })
    @PostMapping("/cmmn-management/timer-jobs/{jobId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void executeTimerJobAction(@ApiParam(name = "jobId") @PathVariable String jobId, @RequestBody TimerJobActionRequest actionRequest) {
        if (actionRequest == null || !(MOVE_ACTION.equals(actionRequest.getAction()) || RESCHEDULE_ACTION.equals(actionRequest.getAction()))) {
            throw new FlowableIllegalArgumentException("Invalid action, only 'move' or 'reschedule' are supported.");
        }
        
        Job job = getTimerJobById(jobId);

        if (MOVE_ACTION.equals(actionRequest.getAction())) {
            try {
                managementService.moveTimerToExecutableJob(job.getId());
            } catch (FlowableObjectNotFoundException e) {
                // Re-throw to have consistent error-messaging across REST-api
                throw new FlowableObjectNotFoundException("Could not find a timer job with id '" + jobId + "'.", Job.class);
            }
        } else if (RESCHEDULE_ACTION.equals(actionRequest.getAction())) {
            if (actionRequest.getDueDate() == null) {
                throw new FlowableIllegalArgumentException("Invalid reschedule timer action. Reschedule timer actions must have a valid due date");
            }
            try {
                managementService.rescheduleTimeDateValueJob(job.getId(), actionRequest.getDueDate());
            } catch (FlowableObjectNotFoundException e) {

View on GitHub (pinned to d6d39ce1c6)