{"record":{"id":"81470ed9d65750e7","repo":"flowable/flowable-engine","slug":"provided-exception-message-is-null-81470e","errorCode":null,"errorMessage":"Provided exception message is null","messagePattern":"Provided exception message is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/ExternalWorkerJobQueryImpl.java","lineNumber":456,"sourceCode":"            this.duedateLowerThan = date;\n        }\n        return this;\n    }\n\n    @Override\n    public ExternalWorkerJobQuery withException() {\n        if (inOrStatement) {\n            this.currentOrQueryObject.withException = true;\n        } else {\n            this.withException = true;\n        }\n        return this;\n    }\n\n    @Override\n    public ExternalWorkerJobQuery exceptionMessage(String exceptionMessage) {\n        if (exceptionMessage == null) {\n            throw new FlowableIllegalArgumentException(\"Provided exception message is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.exceptionMessage = exceptionMessage;\n        } else {\n            this.exceptionMessage = exceptionMessage;\n        }\n        return this;\n    }\n\n    @Override\n    public ExternalWorkerJobQuery jobTenantId(String tenantId) {\n        if (tenantId == null) {\n            throw new FlowableIllegalArgumentException(\"Provided tenant id is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.tenantId = tenantId;\n        } else {\n            this.tenantId = tenantId;","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/ExternalWorkerJobQueryImpl.java#L438-L474","documentation":"ExternalWorkerJobQueryImpl.exceptionMessage(String) rejects a null exception message because a null filter value would yield an invalid equality predicate on the EXCEPTION_MSG_ column. Flowable validates required query arguments eagerly and throws FlowableIllegalArgumentException. Note it filters by exact message, not substring.","triggerScenarios":"Calling exceptionMessage(null), e.g. when copying an exception message from a Job entity whose getExceptionMessage() returned null, or a search input that was never set.","commonSituations":"Admin consoles searching failed jobs by error text; retry tooling filtering on a job's stored exception message when no exception was recorded.","solutions":["Only call exceptionMessage(msg) when msg != null, otherwise skip the filter","If searching failed jobs, combine jobWithException() with a non-null message","Branch on message presence instead of passing the null value through","Normalize/escape the message if matching recorded exception messages"],"exampleFix":"// before\nquery.jobWithException().exceptionMessage(failedJob.getExceptionMessage());\n// after\nquery.jobWithException();\nif (failedJob.getExceptionMessage() != null) {\n    query.exceptionMessage(failedJob.getExceptionMessage());\n}","handlingStrategy":"validation","validationCode":"if (exceptionMessage != null) {\n    externalWorkerJobQuery.jobWithException().exceptionMessage(exceptionMessage);\n}","typeGuard":"boolean hasMessage(String m) { return m != null && !m.isEmpty(); }","tryCatchPattern":null,"preventionTips":["Remember Job.getExceptionMessage() returns null for jobs without exceptions","Branch on message presence before filtering","Combine with jobWithException() so the filter is meaningful"],"tags":["flowable","null-argument","query-api"],"backgroundTag":"null-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"}