flowable/flowable-engine · error · FlowableIllegalArgumentException
jobId and job is null
Error message
jobId and job is null
What it means
MoveDeadLetterJobToExecutableJobCmd.execute() requires a dead-letter jobId; if it is null it throws FlowableIllegalArgumentException with the (legacy) message 'jobId and job is null'. The command moves a job out of the dead-letter table back to the executable job table, which is impossible without an id.
Solutions
- Null-check the dead-letter job id before invoking moveDeadLetterJobToExecutableJob.
- Skip or log entries with null ids in batch-retry loops instead of passing them through.
- Fix the source (query/UI form) that produced a null id.
Example fix
// before
managementService.moveDeadLetterJobToExecutableJob(job.getId(), 3);
// after
if (job != null && job.getId() != null) {
managementService.moveDeadLetterJobToExecutableJob(job.getId(), 3);
} Defensive patterns
Strategy: validation
Validate before calling
if (jobId == null || jobId.isEmpty()) throw new IllegalArgumentException("dead-letter jobId required"); Type guard
boolean movable = job != null && job.getId() != null;
Try / catch
try { managementService.moveDeadLetterJobToExecutableJob(jobId, retries); } catch (FlowableIllegalArgumentException e) { log.error("Invalid jobId: {}", e.getMessage()); } Prevention
- Filter null ids out of dead-letter retry batches
- Validate UI/form inputs before invoking management APIs
- Wrap management calls in helpers that enforce preconditions
When it happens
Trigger: Calling ManagementService.moveDeadLetterJobToExecutableJob(jobId, ...) with a null jobId, or invoking the command programmatically without setting the id.
Common situations: Id pulled from a nullable search result or loop variable that was null for the current iteration; admin UI passes an unset field; batch retry scripts that do not filter null ids.
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/ebf008f3436fe020.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/MoveDeadLetterJobToExecutableJobCmd.java:51
private static final Logger LOGGER = LoggerFactory.getLogger(MoveDeadLetterJobToExecutableJobCmd.class);
protected JobServiceConfiguration jobServiceConfiguration;
protected String jobId;
protected int retries;
public MoveDeadLetterJobToExecutableJobCmd(String jobId, int retries, JobServiceConfiguration jobServiceConfiguration) {
this.jobId = jobId;
this.retries = retries;
this.jobServiceConfiguration = jobServiceConfiguration;
}
@Override
public Job execute(CommandContext commandContext) {
if (jobId == null) {
throw new FlowableIllegalArgumentException("jobId and job is null");
}
DeadLetterJobEntity job = jobServiceConfiguration.getDeadLetterJobEntityManager().findById(jobId);
if (job == null) {
throw new JobNotFoundException(jobId);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Moving deadletter job to executable job table {}", job.getId());
}
return jobServiceConfiguration.getJobManager().moveDeadLetterJobToExecutableJob(job, retries);
}
public String getJobId() {
return jobId;
}
View on GitHub (pinned to d6d39ce1c6)