{"record":{"id":"f3ef25ed47fdc10e","repo":"flowable/flowable-engine","slug":"unexpected-exception-getting-variable-data-f3ef25","errorCode":null,"errorMessage":"Unexpected exception getting variable data","messagePattern":"Unexpected exception getting variable data","errorType":"exception","errorClass":"FlowableException","httpStatus":500,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricDetailDataResource.java","lineNumber":86,"sourceCode":"                result = (byte[]) variable.getValue();\n                response.setContentType(\"application/octet-stream\");\n\n            } else if (RestResponseFactory.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    public RestVariable getVariableFromRequest(boolean includeBinary, String detailId) {\n        Object value = null;\n        HistoricVariableUpdate variableUpdate = null;\n        HistoricDetail detailObject = historyService.createHistoricDetailQuery().id(detailId).singleResult();\n        if (detailObject instanceof HistoricVariableUpdate) {\n            variableUpdate = (HistoricVariableUpdate) detailObject;\n            value = variableUpdate.getValue();\n        }\n        \n        if (restApiInterceptor != null) {\n            restApiInterceptor.accessHistoryDetailById(detailObject);\n        }\n\n        if (value == null) {\n            throw new FlowableObjectNotFoundException(\"Historic detail '\" + detailId + \"' does not have a variable value.\", VariableInstanceEntity.class);","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricDetailDataResource.java#L68-L104","documentation":"While serializing or streaming the variable's binary value to the HTTP response, an IOException occurred; Flowable wraps it in a FlowableException with this generic message and the original cause attached. It signals an infrastructure/streaming failure rather than a business-rule violation.","triggerScenarios":"IOException during outputStream.writeObject / toByteArray while building the response for GET /history/historic-detail/{detailId}/data, e.g. serialization of a non-serializable object reaching the byte-array path, or memory/IO failures.","commonSituations":"Storing objects that fail java serialization at runtime; low heap causing OutOfMemory wrapped as IOException paths; corrupted serialized payloads in the history table.","solutions":["Inspect the wrapped cause (getCause()) to identify the underlying IOException","Ensure values stored as serializable variables implement Serializable with a stable serialVersionUID","Catch FlowableException on this endpoint and retry or re-query via the JSON variable endpoint","Verify sufficient memory and disk health on the REST server"],"exampleFix":"// before\nruntimeService.setVariable(taskId, \"config\", new NonSerializableConfig())\n\n// after\nruntimeService.setVariable(taskId, \"config\", serializableConfig) // implements Serializable","handlingStrategy":"try-catch","validationCode":"if (!Buffer.isBuffer(value) && typeof value !== 'object') {\n  throw new Error('Only serializable/binary values can be fetched via the data endpoint');\n}","typeGuard":null,"tryCatchPattern":"try { return await getVariableData(detailId); } catch (e) { if (/Unexpected exception getting variable data/.test(e.message)) { log.error('cause:', e.cause); throw new StorageReadError(e); } throw e; }","preventionTips":["Store only Serializable objects with fixed serialVersionUID as variables","Monitor server memory/IO health","Prefer storing byte[] instead of arbitrary complex objects"],"tags":["rest-api","flowable","io-exception","serialization"],"backgroundTag":"file-read-failed","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"}