{"record":{"id":"80a47b6a75f798dc","repo":"flowable/flowable-engine","slug":"variable-value-is-missing-for-variable-variab","errorCode":null,"errorMessage":"Variable value is missing for variable: \" + variable.getName()","messagePattern":"Variable value is missing for variable: \" \\+ variable\\.getName\\(\\)","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricProcessInstanceBaseResource.java","lineNumber":317,"sourceCode":"    }\n\n    protected HistoricProcessInstance getHistoricProcessInstanceFromRequestWithoutAccessCheck(String processInstanceId) {\n        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();\n        if (processInstance == null) {\n            throw new FlowableObjectNotFoundException(\"Could not find a process instance with id '\" + processInstanceId + \"'.\", HistoricProcessInstance.class);\n        }\n\n        return processInstance;\n    }\n\n    protected void addVariables(HistoricProcessInstanceQuery processInstanceQuery, 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.getVariableOperation() != QueryVariableOperation.EXISTS && variable.getVariableOperation() != QueryVariableOperation.NOT_EXISTS) {\n                if (variable.getValue() == null) {\n                    throw new FlowableIllegalArgumentException(\"Variable value is missing for variable: \" + variable.getName());\n                }\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 && variable.getVariableOperation() != QueryVariableOperation.EQUALS) {\n                throw new FlowableIllegalArgumentException(\"Value-only query (without a variable-name) is only supported when using 'equals' operation.\");\n            }\n\n            switch (variable.getVariableOperation()) {\n\n            case EQUALS:\n                if (nameLess) {\n                    processInstanceQuery.variableValueEquals(actualValue);\n                } else {","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricProcessInstanceBaseResource.java#L299-L335","documentation":"For EXISTS/NOT_EXISTS operations the value is optional, but every other variable query operation requires a value to compare against. addVariables throws FlowableIllegalArgumentException when variable.getValue() is null for those operations, since the resulting query predicate would be meaningless.","triggerScenarios":"GET /history/historic-process-instances?variable=name|equals| (empty value) or a variable filter with an operation like gt/like/equals but no value supplied.","commonSituations":"Client omits the value when the variable is empty; null values lost during URL-encoding; frameworks dropping empty query segments.","solutions":["Provide the value in the variable filter for all operations except exists/notExists","Use exists/notExists if you only want to test variable presence without a value","Catch FlowableIllegalArgumentException (HTTP 400) and validate filter completeness before sending"],"exampleFix":"// before\nGET /history/historic-process-instances?variable=status|equals|\n\n// after\nGET /history/historic-process-instances?variable=status|equals|ACTIVE\n// or presence check:\nGET /history/historic-process-instances?variable=status|exists|","handlingStrategy":"validation","validationCode":"for (const v of variables) {\n  const presenceOnly = v.operation === 'exists' || v.operation === 'notExists';\n  if (!presenceOnly && (v.value === undefined || v.value === null)) {\n    throw new Error(`Variable ${v.name}: value required for ${v.operation}`);\n  }\n}","typeGuard":"function needsValue(v) { return v.operation !== 'exists' && v.operation !== 'notExists'; }","tryCatchPattern":"try { return await queryHistoricInstances(vars); } catch (e) { if (e.status === 400 && /Variable value is missing/.test(e.message)) fixFilters(vars); else throw e; }","preventionTips":["Use exists/notExists for presence checks without values","Validate filter completeness before sending","Handle empty values explicitly rather than omitting them"],"tags":["rest-api","flowable","query-parameter","validation"],"backgroundTag":"missing-required-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"}