{"record":{"id":"f4a60a1fd2594d38","repo":"flowable/flowable-engine","slug":"provided-sub-scope-id-is-null-f4a60a","errorCode":null,"errorMessage":"Provided sub scope id is null","messagePattern":"Provided sub scope id is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/DeadLetterJobQueryImpl.java","lineNumber":275,"sourceCode":"            this.scopeIds = scopeIds;\n        }\n        return this;\n    }\n    \n    @Override\n    public DeadLetterJobQueryImpl withoutScopeId() {\n        if (inOrStatement) {\n            this.currentOrQueryObject.withoutScopeId = true;\n        } else {\n            this.withoutScopeId = true;\n        }\n        return this;\n    }\n    \n    @Override\n    public DeadLetterJobQueryImpl subScopeId(String subScopeId) {\n        if (subScopeId == null) {\n            throw new FlowableIllegalArgumentException(\"Provided sub scope id is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.subScopeId = subScopeId;\n        } else {\n            this.subScopeId = subScopeId;\n        }\n        return this;\n    }\n    \n    @Override\n    public DeadLetterJobQueryImpl scopeType(String scopeType) {\n        if (scopeType == null) {\n            throw new FlowableIllegalArgumentException(\"Provided scope type is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.scopeType = scopeType;\n        } else {\n            this.scopeType = scopeType;","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/DeadLetterJobQueryImpl.java#L257-L293","documentation":"DeadLetterJobQueryImpl.subScopeId() throws FlowableIllegalArgumentException when the subScopeId parameter is null. subScopeId targets a nested scope such as a plan item instance (the planItemInstanceId() wrapper delegates here, typically alongside scopeType), and null is rejected at query construction time.","triggerScenarios":"Calling deadLetterJobQuery().subScopeId(null), or planItemInstanceId(null) which delegates to subScopeId; passing a plan item instance id obtained from a failed lookup or an unset entity field.","commonSituations":"CMMN case work where the plan item instance was completed/removed and its lookup now returns null; generic helper methods that forward optional sub-scope ids without guards; test fixtures missing the id.","solutions":["Null-check the subScopeId (or planItemInstanceId) before calling","Omit the sub-scope filter to search jobs of the whole parent scope","Remember planItemInstanceId(...) also sets scopeType - treat id and type as a pair and guard both","Investigate why the plan item instance id is missing (wrong stage, case already terminated)"],"exampleFix":"// before\nquery.planItemInstanceId(planItemId); // throws when planItemId is null\n\n// after\nDeadLetterJobQuery query = jobService.createDeadLetterJobQuery();\nif (planItemId != null) {\n    query = query.planItemInstanceId(planItemId);\n}","handlingStrategy":"validation","validationCode":"if (planItemInstanceId != null) {\n    query = query.planItemInstanceId(planItemInstanceId);\n}","typeGuard":"boolean hasSubScopeId(String subScopeId) { return subScopeId != null && !subScopeId.trim().isEmpty(); }","tryCatchPattern":"try {\n    return query.subScopeId(subScopeId).list();\n} catch (FlowableIllegalArgumentException e) {\n    throw new InvalidQueryRequestException(\"subScopeId/planItemInstanceId must not be null\", e);\n}","preventionTips":["Handle plan item instances that may no longer exist (lookups can return null)","Guard planItemInstanceId(...) calls - they delegate to subScopeId and also set scopeType","Drop the sub-scope filter to search the whole parent scope","Validate CMMN-related ids at the boundary before query construction"],"tags":["flowable","null-argument","query-builder","cmmn"],"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"}