{"record":{"id":"916f24cef35a46f4","repo":"flowable/flowable-engine","slug":"the-job-id-is-mandatory-but-jobid-has-been-p-916f24","errorCode":null,"errorMessage":"The job id is mandatory, but '${jobId}' has been provided.","messagePattern":"The job id is mandatory, but '(.+?)' has been provided\\.","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/SetTimerJobRetriesCmd.java","lineNumber":42,"sourceCode":"import org.flowable.job.api.Job;\nimport org.flowable.job.service.JobServiceConfiguration;\nimport org.flowable.job.service.event.impl.FlowableJobEventBuilder;\nimport org.flowable.job.service.impl.persistence.entity.TimerJobEntity;\n\n/**\n * @author Tijs Rademakers\n */\npublic class SetTimerJobRetriesCmd implements Command<Void>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n\n    protected final String jobId;\n    protected final int retries;\n    protected JobServiceConfiguration jobServiceConfiguration;\n\n    public SetTimerJobRetriesCmd(String jobId, int retries, JobServiceConfiguration jobServiceConfiguration) {\n        if (jobId == null || jobId.length() < 1) {\n            throw new FlowableIllegalArgumentException(\"The job id is mandatory, but '\" + jobId + \"' has been provided.\");\n        }\n        if (retries < 0) {\n            throw new FlowableIllegalArgumentException(\"The number of job retries must be a non-negative Integer, but '\" + retries + \"' has been provided.\");\n        }\n        this.jobId = jobId;\n        this.retries = retries;\n        this.jobServiceConfiguration = jobServiceConfiguration;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        TimerJobEntity job = jobServiceConfiguration.getTimerJobEntityManager().findById(jobId);\n        if (job != null) {\n\n            job.setRetries(retries);\n\n            FlowableEventDispatcher eventDispatcher = jobServiceConfiguration.getEventDispatcher();\n            if (eventDispatcher != null && eventDispatcher.isEnabled()) {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/SetTimerJobRetriesCmd.java#L24-L60","documentation":"Flowable throws this FlowableIllegalArgumentException in the SetTimerJobRetriesCmd constructor when the timer job id argument is null or an empty/blank string. The job id is the primary key used to locate the timer job entity, so without it the command can never succeed. It is fail-fast validation in the command constructor before any database access.","triggerScenarios":"Calling new SetTimerJobRetriesCmd(null, retries, config) or SetTimerJobRetriesCmd(\"\", retries, config), or indirectly invoking ManagementService/setTimerJobRetries-style APIs where the jobId variable passed in was never initialized or came back empty from an upstream lookup.","commonSituations":"Passing a variable that was assigned from a map/getter that returned null; copying code from SetJobRetriesCmd and forgetting to supply the timer job id; deserializing a job id from config or a request payload where the field is optional and empty.","solutions":["Ensure a non-empty timer job id is resolved before constructing the command","Null/blank-check the id at the API boundary and surface a clear validation message to the caller","Verify the id comes from the correct entity (a timer job id, not a process/execution id)","Log the value being passed to catch empty-string propagation"],"exampleFix":"// before\nString jobId = variables.get(\"jobId\");\nmanagementService.setTimerJobRetries(jobId, 3);\n// after\nString jobId = variables.get(\"jobId\");\nif (jobId == null || jobId.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"timerJobId must be provided\");\n}\nmanagementService.setTimerJobRetries(jobId, 3);","handlingStrategy":"validation","validationCode":"if (jobId == null || jobId.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"A non-empty timer job id is required\");\n}\nmanagementService.setTimerJobRetries(jobId, retries);","typeGuard":"boolean isValidJobId(String id) { return id != null && !id.trim().isEmpty(); }","tryCatchPattern":null,"preventionTips":["Resolve job ids from a TimerJobQuery, not free-form input","Validate ids at API boundaries before constructing commands","Log the id value when constructing retry commands to catch empty propagation"],"tags":["validation","flowable","argument-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}