{"record":{"id":"22e7aab5f95a1fb5","repo":"flowable/flowable-engine","slug":"invalid-action-only-move-or-movetohistoryjob","errorCode":null,"errorMessage":"Invalid action, only 'move' or 'moveToHistoryJob' is supported.","messagePattern":"Invalid action, only 'move' or 'moveToHistoryJob' is supported\\.","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/management/JobCollectionResource.java","lineNumber":200,"sourceCode":"        }\n        \n        if (restApiInterceptor != null) {\n            restApiInterceptor.accessJobInfoWithQuery(query);\n        }\n\n        return paginateList(allRequestParams, query, \"id\", JobQueryProperties.PROPERTIES, restResponseFactory::createJobResponseList);\n    }\n\n    @ApiOperation(value = \"Move a bulk of deadletter jobs. Accepts 'move' and 'moveToHistoryJob' as action.\", tags = { \"Jobs\" }, code = 204)\n    @ApiResponses(value = {\n            @ApiResponse(code = 204, message = \"Indicates the dead letter jobs where moved. Response-body is intentionally empty.\"),\n            @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.\")\n    })\n    @ResponseStatus(value = HttpStatus.NO_CONTENT)\n    @PostMapping(\"/cmmn-management/deadletter-jobs\")\n    public void executeDeadLetterJobAction(@RequestBody BulkMoveDeadLetterActionRequest actionRequest) {\n        if (actionRequest == null || !(MOVE_ACTION.equals(actionRequest.getAction()) || MOVE_TO_HISTORY_JOB_ACTION.equals(actionRequest.getAction()))) {\n            throw new FlowableIllegalArgumentException(\"Invalid action, only 'move' or 'moveToHistoryJob' is supported.\");\n        }\n\n        Collection<String> jobIds = actionRequest.getJobIds();\n        long existingJobIdCount = managementService.createDeadLetterJobQuery().jobIds(jobIds).count();\n        if (jobIds.size() != existingJobIdCount) {\n            List<Job> foundJobs = managementService.createDeadLetterJobQuery().jobIds(jobIds).list();\n            for (Job job : foundJobs) {\n                jobIds.remove(job.getId());\n            }\n            throw new FlowableObjectNotFoundException(\n                    \"Could not find a dead letter job(s) with id(s) {\" + jobIds.stream().collect(Collectors.joining(\",\")) + \"}\", Job.class);\n        }\n        if (MOVE_ACTION.equals(actionRequest.getAction())) {\n            if (restApiInterceptor != null) {\n                restApiInterceptor.bulkMoveDeadLetterJobs(actionRequest.getJobIds(), MOVE_ACTION);\n            }\n            managementService.bulkMoveDeadLetterJobs(actionRequest.getJobIds(), cmmnEngineConfiguration.getAsyncExecutorNumberOfRetries());\n        } else if (MOVE_TO_HISTORY_JOB_ACTION.equals(actionRequest.getAction())) {","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/management/JobCollectionResource.java#L182-L218","documentation":"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.","triggerScenarios":"POST /cmmn-management/deadletter-jobs with a body whose action is 'retry', 'delete', 'MOVE', empty, or absent — anything not exactly 'move' or 'moveToHistoryJob'.","commonSituations":"Clients assuming a 'retry' action exists (older Flowable versions used different semantics); case-sensitive mismatch ('Move'); missing action field after a request-body refactor.","solutions":["Set action to exactly 'move' or 'moveToHistoryJob' in the request body.","Ensure the JSON body matches BulkMoveDeadLetterActionRequest with a non-null action and jobIds list.","For other job handling (delete/retry), use the engine ManagementService API or a different endpoint."],"exampleFix":"// before\n{\"action\":\"retry\",\"jobIds\":[\"42\"]}\n// after\n{\"action\":\"move\",\"jobIds\":[\"42\"]}","handlingStrategy":"validation","validationCode":"const VALID_ACTIONS=[\"move\",\"moveToHistoryJob\"];\nif (!VALID_ACTIONS.includes(actionRequest.action)) throw new Error(`action must be 'move' or 'moveToHistoryJob'`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Copy action strings from the API docs/tests exactly (case-sensitive).","Always send a non-null action field with jobIds.","Use SDK constants for action names."],"tags":["rest-api","validation","jobs"],"backgroundTag":"invalid-enum-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}