{"record":{"id":"7dfb9ff51f0cb0fa","repo":"flowable/flowable-engine","slug":"the-variable-does-not-have-a-binary-data-stream-7dfb9f","errorCode":null,"errorMessage":"The variable does not have a binary data stream.","messagePattern":"The variable does not have a binary data stream\\.","errorType":"http","errorClass":"FlowableObjectNotFoundException","httpStatus":404,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/variable/HistoricVariableInstanceDataResource.java","lineNumber":77,"sourceCode":"    @ResponseBody\n    public byte[] getVariableData(@ApiParam(name = \"varInstanceId\") @PathVariable(\"varInstanceId\") String varInstanceId, HttpServletResponse response) {\n        try {\n            byte[] result = null;\n            RestVariable variable = getVariableFromRequest(true, varInstanceId);\n            if (CmmnRestResponseFactory.BYTE_ARRAY_VARIABLE_TYPE.equals(variable.getType())) {\n                result = (byte[]) variable.getValue();\n                response.setContentType(\"application/octet-stream\");\n\n            } else if (CmmnRestResponseFactory.SERIALIZABLE_VARIABLE_TYPE.equals(variable.getType())) {\n                ByteArrayOutputStream buffer = new ByteArrayOutputStream();\n                ObjectOutputStream outputStream = new ObjectOutputStream(buffer);\n                outputStream.writeObject(variable.getValue());\n                outputStream.close();\n                result = buffer.toByteArray();\n                response.setContentType(\"application/x-java-serialized-object\");\n\n            } else {\n                throw new FlowableObjectNotFoundException(\"The variable does not have a binary data stream.\", null);\n            }\n            return result;\n\n        } catch (IOException ioe) {\n            // Re-throw IOException\n            throw new FlowableException(\"Unexpected exception getting variable data\", ioe);\n        }\n    }\n}\n","sourceCodeStart":59,"sourceCodeEnd":87,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/variable/HistoricVariableInstanceDataResource.java#L59-L87","documentation":"HistoricVariableInstanceDataResource.getVariableData returns the binary/serializable content of a historic variable. For byte-array and serializable types it reads the raw bytes or deserializes the value; if the variable has no binary data stream (e.g. it is a plain string/number or the bytes were deleted), it throws FlowableObjectNotFoundException.","triggerScenarios":"GET /cmmn-history/historic-variable-instances/{variableId}/data on a variable whose value is a primitive type (string, integer, date) rather than byte[] or Serializable, or whose blob data is no longer present.","commonSituations":"Scripts assuming every variable has downloadable binary data; variables stored in a database where the act_ge_bytearray row was purged/cleaned; querying serializable variables after DB cleanup jobs removed the data.","solutions":["Check the variable's type before requesting /data; only byte and serializable variables have a binary stream.","Handle HTTP 404 from the /data endpoint as 'no binary content' rather than a hard failure.","If the blob was deleted by history/purge jobs, re-run the process case or configure retention so variable blobs are kept as long as needed."],"exampleFix":"// before\nbyte[] data = client.get(\"/cmmn-history/historic-variable-instances/\" + id + \"/data\");\n// after\nif (variable.getType().equals(\"byte\") || variable.getType().equals(\"serializable\")) {\n    byte[] data = client.get(\"/cmmn-history/historic-variable-instances/\" + id + \"/data\");\n}","handlingStrategy":"try-catch","validationCode":"const BINARY_TYPES=[\"byte\",\"serializable\"];\nif (!BINARY_TYPES.includes(variable.type)) throw new Error(`Variable ${variable.id} has no binary data`);","typeGuard":"const hasBinary = v => v.type === 'byte' || v.type === 'serializable';","tryCatchPattern":"try { data = fetch(url) } catch (e) { if (e.status === 404) { /* no binary content: treat as empty */ } else { throw e } }","preventionTips":["Check variable type before calling /data.","Treat 404 on /data as expected for primitive variables.","Don't configure history cleanup that removes blobs you still need."],"tags":["rest-api","resource-not-found","variables"],"backgroundTag":"resource-not-found","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"}