{"record":{"id":"0c73435633396fe3","repo":"flowable/flowable-engine","slug":"requested-number-of-jobs-must-not-be-smaller-than","errorCode":null,"errorMessage":"requested number of jobs must not be smaller than 1","messagePattern":"requested number of jobs must not be smaller than 1","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/AcquireExternalWorkerJobsCmd.java","lineNumber":61,"sourceCode":"\n    public AcquireExternalWorkerJobsCmd(String workerId, int numberOfJobs, ExternalWorkerJobAcquireBuilderImpl builder,\n            JobServiceConfiguration jobServiceConfiguration) {\n        \n        this.workerId = workerId;\n        this.numberOfJobs = numberOfJobs;\n        this.builder = builder;\n        this.jobServiceConfiguration = jobServiceConfiguration;\n    }\n\n    @Override\n    public List<AcquiredExternalWorkerJob> execute(CommandContext commandContext) {\n        String topic = builder.getTopic();\n        if (StringUtils.isEmpty(topic)) {\n            throw new FlowableIllegalArgumentException(\"topic must not be empty\");\n        }\n\n        if (numberOfJobs < 1) {\n            throw new FlowableIllegalArgumentException(\"requested number of jobs must not be smaller than 1\");\n        }\n\n        if (StringUtils.isEmpty(workerId)) {\n            throw new FlowableIllegalArgumentException(\"workerId must not be empty\");\n        }\n\n        ExternalWorkerJobEntityManager externalWorkerJobEntityManager = jobServiceConfiguration.getExternalWorkerJobEntityManager();\n        InternalJobManager internalJobManager = jobServiceConfiguration.getInternalJobManager();\n\n        List<ExternalWorkerJobEntity> jobs = externalWorkerJobEntityManager.findExternalJobsToExecute(builder, numberOfJobs);\n\n        int lockTimeInMillis = (int) builder.getLockDuration().abs().toMillis();\n        List<AcquiredExternalWorkerJob> acquiredJobs = new ArrayList<>(jobs.size());\n\n        for (ExternalWorkerJobEntity job : jobs) {\n            lockJob(commandContext, job, lockTimeInMillis);\n            Map<String, Object> variables = null;\n            if (internalJobManager != null) {","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/AcquireExternalWorkerJobsCmd.java#L43-L79","documentation":"Thrown by AcquireExternalWorkerJobsCmd.execute() when numberOfJobs is less than 1. Flowable uses this value as the max result count for the acquisition query; a zero or negative value is treated as invalid input and rejected before querying.","triggerScenarios":"Passing 0 or a negative number to acquireAndLock(numberOfJobs, workerId, lockDuration); numberOfJobs computed from a batch-size config that defaulted to 0; arithmetic (e.g. remaining = total - done) yielding zero or negative.","commonSituations":"Batch-size property unset and parsed as 0; a poll loop computing the next batch size from quotas; copy-pasted code with placeholder 0 never replaced.","solutions":["Ensure numberOfJobs >= 1, e.g. Math.max(1, configuredBatchSize)","Validate the batch-size configuration at worker startup and reject non-positive values","If nothing should be acquired, skip the call entirely instead of passing 0"],"exampleFix":"// before\nint numberOfJobs = config.getBatchSize(); // may be 0\nbuilder.acquireAndLock(numberOfJobs, workerId, lockDuration);\n// after\nint numberOfJobs = Math.max(1, config.getBatchSize());\nbuilder.acquireAndLock(numberOfJobs, workerId, lockDuration);","handlingStrategy":"validation","validationCode":"if (numberOfJobs < 1) {\n    throw new IllegalArgumentException(\"numberOfJobs must be >= 1\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    acquireBuilder.topic(topic).acquireAndLock(numberOfJobs, workerId, lockDuration);\n} catch (FlowableIllegalArgumentException e) {\n    LOGGER.error(\"Acquire rejected: {}\", e.getMessage());\n}","preventionTips":["Default batch size to a positive value when config is missing","Clamp computed batch sizes with Math.max(1, n)","Skip the acquire call when no capacity is available instead of passing 0"],"tags":["validation","flowable","acquire"],"backgroundTag":"invalid-argument-value","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"}