{"record":{"id":"9e5137374a2a1d8b","repo":"flowable/flowable-engine","slug":"variable-operation-is-missing-for-variable-vari","errorCode":null,"errorMessage":"Variable operation is missing for variable: ${variable.getName()}","messagePattern":"Variable operation is missing for variable: (.+?)","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/caze/HistoricCaseInstanceBaseResource.java","lineNumber":311,"sourceCode":"            restApiInterceptor.accessHistoryCaseInfoById(caseInstance);\n        }\n        \n        return caseInstance;\n    }\n\n    protected HistoricCaseInstance getHistoricCaseInstanceFromRequestWithoutAccessCheck(String caseInstanceId) {\n        HistoricCaseInstance caseInstance = historyService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstanceId).singleResult();\n        if (caseInstance == null) {\n            throw new FlowableObjectNotFoundException(\"Could not find a case instance with id '\" + caseInstanceId + \"'.\", HistoricCaseInstance.class);\n        }\n\n        return caseInstance;\n    }\n\n    protected void addVariables(HistoricCaseInstanceQuery caseInstanceQuery, 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","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/caze/HistoricCaseInstanceBaseResource.java#L293-L329","documentation":"FlowableIllegalArgumentException raised while building a historic case instance query from REST request variables: a QueryVariable entry has no 'operation' field set. The operation tells the engine how to compare the variable value, so it is mandatory.","triggerScenarios":"POST to the historic case instance query collection with a variable JSON object like {\"name\":\"x\",\"value\":1} but no \"operation\" field (e.g. missing \"operation\":\"equals\").","commonSituations":"Hand-written JSON queries omitting 'operation'; client SDK upgrade changed the field name; copy-pasted payload that only included name/value.","solutions":["Add the operation field to each variable object, e.g. {\"name\":\"x\",\"value\":1,\"operation\":\"equals\"}","Use operation EXISTS/NOT_EXISTS for presence checks (value not required)","Validate the request body client-side before sending","Check client serialization maps the operation enum correctly"],"exampleFix":"// before\n{\"variables\":[{\"name\":\"status\",\"value\":\"active\"}]}\n// after\n{\"variables\":[{\"name\":\"status\",\"value\":\"active\",\"operation\":\"equals\"}]}","handlingStrategy":"validation","validationCode":"for (Map<String,Object> v : variables) {\n  if (!v.containsKey(\"operation\")) throw new IllegalArgumentException(\"Missing operation for variable \" + v.get(\"name\"));\n}","typeGuard":"boolean hasOperation(Map<String,Object> v) { return v.get(\"operation\") != null; }","tryCatchPattern":"try { ... } catch (FlowableIllegalArgumentException e) {\n  return badRequest(\"Invalid query variable: \" + e.getMessage());\n}","preventionTips":["Always include operation in every variable object","Prefer an SDK/typed client that enforces the field","Validate the query payload before POSTing"],"tags":["rest-api","validation","query","missing-field"],"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-14T05:17:10.506Z"}