flowable/flowable-engine · error · FlowableIllegalArgumentException

Invalid action, only 'move' or 'moveToHistoryJob' is support

Error message

Invalid action, only 'move' or 'moveToHistoryJob' is supported.

What it means

executeDeadLetterJobAction performs bulk actions on dead letter jobs (POST /cmmn-management/deadletter-jobs). Only 'move' (back to jobs) and 'moveToHistoryJob' actions are allowed; any other or missing action string throws FlowableIllegalArgumentException.

Source

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

        }
        
        if (restApiInterceptor != null) {
            restApiInterceptor.accessJobInfoWithQuery(query);
        }

        return paginateList(allRequestParams, query, "id", JobQueryProperties.PROPERTIES, restResponseFactory::createJobResponseList);
    }

    @ApiOperation(value = "Move a bulk of deadletter jobs. Accepts 'move' and 'moveToHistoryJob' as action.", tags = { "Jobs" }, code = 204)
    @ApiResponses(value = {
            @ApiResponse(code = 204, message = "Indicates the dead letter jobs where moved. Response-body is intentionally empty."),
            @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.")
    })
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping("/cmmn-management/deadletter-jobs")
    public void executeDeadLetterJobAction(@RequestBody BulkMoveDeadLetterActionRequest actionRequest) {
        if (actionRequest == null || !(MOVE_ACTION.equals(actionRequest.getAction()) || MOVE_TO_HISTORY_JOB_ACTION.equals(actionRequest.getAction()))) {
            throw new FlowableIllegalArgumentException("Invalid action, only 'move' or 'moveToHistoryJob' is supported.");
        }

        Collection<String> jobIds = actionRequest.getJobIds();
        long existingJobIdCount = managementService.createDeadLetterJobQuery().jobIds(jobIds).count();
        if (jobIds.size() != existingJobIdCount) {
            List<Job> foundJobs = managementService.createDeadLetterJobQuery().jobIds(jobIds).list();
            for (Job job : foundJobs) {
                jobIds.remove(job.getId());
            }
            throw new FlowableObjectNotFoundException(
                    "Could not find a dead letter job(s) with id(s) {" + jobIds.stream().collect(Collectors.joining(",")) + "}", Job.class);
        }
        if (MOVE_ACTION.equals(actionRequest.getAction())) {
            if (restApiInterceptor != null) {
                restApiInterceptor.bulkMoveDeadLetterJobs(actionRequest.getJobIds(), MOVE_ACTION);
            }
            managementService.bulkMoveDeadLetterJobs(actionRequest.getJobIds(), cmmnEngineConfiguration.getAsyncExecutorNumberOfRetries());
        } else if (MOVE_TO_HISTORY_JOB_ACTION.equals(actionRequest.getAction())) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Set action to exactly 'move' or 'moveToHistoryJob' in the request body.
  2. Ensure the JSON body matches BulkMoveDeadLetterActionRequest with a non-null action and jobIds list.
  3. For other job handling (delete/retry), use the engine ManagementService API or a different endpoint.

Example fix

// before
{"action":"retry","jobIds":["42"]}
// after
{"action":"move","jobIds":["42"]}
Defensive patterns

Strategy: validation

Validate before calling

const VALID_ACTIONS=["move","moveToHistoryJob"];
if (!VALID_ACTIONS.includes(actionRequest.action)) throw new Error(`action must be 'move' or 'moveToHistoryJob'`);

Prevention

When it happens

Trigger: POST /cmmn-management/deadletter-jobs with a body whose action is 'retry', 'delete', 'MOVE', empty, or absent — anything not exactly 'move' or 'moveToHistoryJob'.

Common situations: Clients assuming a 'retry' action exists (older Flowable versions used different semantics); case-sensitive mismatch ('Move'); missing action field after a request-body refactor.

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/22e7aab5f95a1fb5. Report an issue: GitHub.