{"record":{"id":"9e16508cb414cad7","repo":"flowable/flowable-engine","slug":"provided-exception-message-is-null","errorCode":null,"errorMessage":"Provided exception message is null","messagePattern":"Provided exception message is null","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/DeadLetterJobQueryImpl.java","lineNumber":519,"sourceCode":"            this.duedateLowerThan = date;\n        }\n        return this;\n    }\n\n    @Override\n    public DeadLetterJobQueryImpl 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 DeadLetterJobQueryImpl 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 DeadLetterJobQueryImpl 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":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/DeadLetterJobQueryImpl.java#L501-L537","documentation":"DeadLetterJobQueryImpl.exceptionMessage(String) requires a non-null exception message since it is used as an exact-match filter in the query. Passing null cannot be distinguished from 'no filter', so FlowableIllegalArgumentException is thrown. Callers that do not want this filter should simply not call the method.","triggerScenarios":"Calling deadLetterJobQuery().exceptionMessage(msg) where msg is null, typically from a variable that failed to capture the job's exception message or from an unset request parameter.","commonSituations":"Reading the exception message from a job/variable that is null (job not yet failed); passing a search term from a REST query parameter that was omitted.","solutions":["Guard with a null check and skip the filter when the message is absent","Use empty-string handling deliberately if 'match everything' semantics are desired (note: null is rejected)","Handle FlowableIllegalArgumentException and surface a user-friendly 'specify an exception message' message"],"exampleFix":"// before\nquery.exceptionMessage(failedJob.getExceptionMessage()); // may be null\n// after\nif (failedJob.getExceptionMessage() != null) {\n    query.exceptionMessage(failedJob.getExceptionMessage());\n}","handlingStrategy":"validation","validationCode":"if (exceptionMessage != null) { query.exceptionMessage(exceptionMessage); }","typeGuard":"boolean hasExceptionMessage(String m) { return m != null; }","tryCatchPattern":"try { query.exceptionMessage(msg); } catch (FlowableIllegalArgumentException e) { log.warn(\"No exception message to filter on\", e); }","preventionTips":["Remember a job that never failed has a null exception message","Guard values read from job entities before reusing them in queries","Treat missing filter values as 'no filter', not null"],"tags":["flowable","job-query","null-argument","string-filter"],"backgroundTag":"null-argument","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"}