{"record":{"id":"a5cc6604f08f1887","repo":"flowable/flowable-engine","slug":"variable-value-is-missing-for-variable-a5cc66","errorCode":null,"errorMessage":"Variable value is missing for variable: ","messagePattern":"Variable value is missing for variable: ","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricVariableInstanceBaseResource.java","lineNumber":105,"sourceCode":"        if (queryRequest.getVariables() != null) {\n            addVariables(query, queryRequest.getVariables());\n        }\n        \n        if (restApiInterceptor != null) {\n            restApiInterceptor.accessHistoryVariableInfoWithQuery(query, queryRequest);\n        }\n\n        return paginateList(allRequestParams, queryRequest, query, \"variableName\", allowedSortProperties,\n                restResponseFactory::createHistoricVariableInstanceResponseList);\n    }\n\n    protected void addVariables(HistoricVariableInstanceQuery variableInstanceQuery, List<QueryVariable> variables) {\n        for (QueryVariable variable : variables) {\n            if (variable.getVariableOperation() == null) {\n                throw new FlowableIllegalArgumentException(\"Variable operation is missing for variable: \" + variable.getName());\n            }\n            if (variable.getValue() == null) {\n                throw new FlowableIllegalArgumentException(\"Variable value is missing for variable: \" + variable.getName());\n            }\n\n            boolean nameLess = variable.getName() == null;\n\n            Object actualValue = restResponseFactory.getVariableValue(variable);\n\n            // A value-only query is only possible using equals-operator\n            if (nameLess) {\n                throw new FlowableIllegalArgumentException(\"Value-only query (without a variable-name) is not supported\");\n            }\n\n            switch (variable.getVariableOperation()) {\n\n            case EQUALS:\n                variableInstanceQuery.variableValueEquals(variable.getName(), actualValue);\n                break;\n\n            default:","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricVariableInstanceBaseResource.java#L87-L123","documentation":"FlowableIllegalArgumentException thrown by addVariables when a QueryVariable entry has an operation but its value is null. A null value cannot be compared, and value-less comparisons (e.g. EXISTS) are not supported by this endpoint, so the request is rejected as invalid.","triggerScenarios":"GET/POST /history/historic-variable-instances with variables=[{\"name\":\"status\",\"operation\":\"EQUALS\",\"value\":null}] — the value key is absent or explicitly null; a JSON body that serializes Java null because the client left the filter input empty.","commonSituations":"Dynamic filter forms where the user left the value field blank but the operation was chosen; serialization frameworks dropping empty strings; API consumers who intended a null-comparison which this endpoint does not support.","solutions":["Provide a concrete value: variables=[{\"name\":\"status\",\"operation\":\"EQUALS\",\"value\":\"active\"}]","Skip the variable entry entirely when the value is empty instead of sending it with null","Convert empty user input to a sentinel or drop the clause before building the query","If you need to match unset variables, this endpoint cannot express it — fetch instances and filter client-side or use a different query API"],"exampleFix":"// before\nconst filter = {name: 'status', operation: 'EQUALS', value: userInput.value}\n// after\nconst clauses = [];\nif (userInput.value !== '' && userInput.value != null) {\n  clauses.push({name: 'status', operation: 'EQUALS', value: userInput.value});\n}\nconst qs = clauses.length ? '?variables=' + encodeURIComponent(JSON.stringify(clauses)) : '';","handlingStrategy":"validation","validationCode":"const valid = clauses.filter(c => c.value !== null && c.value !== undefined && c.value !== '');\nconst qs = valid.length ? '?variables=' + encodeURIComponent(JSON.stringify(valid)) : '';","typeGuard":"function hasValue(c) { return c !== null && c !== undefined && c.value !== null && c.value !== undefined && c.value !== ''; }","tryCatchPattern":"try { return await queryHistoricVariables(clauses); } catch (e) { if (String(e.message).includes('value is missing')) { clauses = clauses.filter(hasValue); return queryHistoricVariables(clauses); } throw e; }","preventionTips":["Drop empty filter fields before constructing the request","Never send explicit null values in variable clauses","Map empty user input to clause omission in the query builder"],"tags":["rest","flowable","query","validation","bad-request"],"backgroundTag":"empty-required-field","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"}