{"record":{"id":"4affcb8b43d28cdf","repo":"flowable/flowable-engine","slug":"provided-sub-scope-id-is-null-4affcb","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/SuspendedJobQueryImpl.java","lineNumber":278,"sourceCode":"            this.scopeIds = scopeIds;\n        }\n        return this;\n    }\n    \n    @Override\n    public SuspendedJobQueryImpl 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 SuspendedJobQueryImpl 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 SuspendedJobQueryImpl 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":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/SuspendedJobQueryImpl.java#L260-L296","documentation":"This FlowableIllegalArgumentException is thrown by SuspendedJobQueryImpl.subScopeId() when the caller passes a null sub scope id. Sub scope ids identify nested scopes (e.g. a plan item within a case) and must be non-null to form a valid filter. The exception is raised at query-build time for fail-fast behavior.","triggerScenarios":"Calling suspendedJobQuery().subScopeId(null) directly, or via planItemInstanceId(null), which delegates to subScopeId().","commonSituations":"Plan item instance id not resolved before querying; passing a variable that is null when the job is not associated with a plan item; generic query builders that do not skip absent filters.","solutions":["Only call subScopeId()/planItemInstanceId() when a real id exists","Resolve the plan item instance first and skip the filter if absent","Validate inputs before building the query","Refactor the query assembly to conditionally add filters"],"exampleFix":"// before\nquery.subScopeId(subScopeId); // may be null\n// after\nif (subScopeId != null) {\n    query.subScopeId(subScopeId);\n}","handlingStrategy":"validation","validationCode":"if (subScopeId != null) {\n    query.subScopeId(subScopeId);\n}","typeGuard":"boolean hasSubScopeId = subScopeId != null && !subScopeId.isBlank();","tryCatchPattern":"try {\n    query.subScopeId(subScopeId);\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"sub scope id is null\")) {\n        // skip sub-scope filtering\n    } else {\n        throw e;\n    }\n}","preventionTips":["Only chain planItemInstanceId() after confirming the plan item exists","Guard optional scope filters in a shared query-builder utility","Null-check engine lookup results before reading their ids","Cover null-filter paths in integration tests"],"tags":["java","flowable","query","null-check","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-14T11:17:12.474Z"}