{"record":{"id":"e48df3f5c9441e48","repo":"flowable/flowable-engine","slug":"deserialized-value-is-not-an-array-of-id-s-read","errorCode":null,"errorMessage":"Deserialized value is not an array of ID's: ${read}","messagePattern":"Deserialized value is not an array of ID's: (.+?)","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/variable/JPAEntityListVariableType.java","lineNumber":165,"sourceCode":"            String[] toStore = ids.toArray(new String[]{});\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            ObjectOutputStream out = new ObjectOutputStream(baos);\n\n            out.writeObject(toStore);\n            return baos.toByteArray();\n        } catch (IOException ioe) {\n            throw new ActivitiException(\"Unexpected exception when serializing JPA id's\", ioe);\n        }\n    }\n\n    protected String[] deserializeIds(byte[] bytes) {\n        try {\n            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);\n            ObjectInputStream in = new ObjectInputStream(bais);\n\n            Object read = in.readObject();\n            if (!(read instanceof String[])) {\n                throw new ActivitiIllegalArgumentException(\"Deserialized value is not an array of ID's: \" + read);\n            }\n\n            return (String[]) read;\n        } catch (IOException ioe) {\n            throw new ActivitiException(\"Unexpected exception when deserializing JPA id's\", ioe);\n        } catch (ClassNotFoundException e) {\n            throw new ActivitiException(\"Unexpected exception when deserializing JPA id's\", e);\n        }\n    }\n\n}\n","sourceCodeStart":147,"sourceCodeEnd":177,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/variable/JPAEntityListVariableType.java#L147-L177","documentation":"Thrown by JPAEntityListVariableType.deserializeIds() when the deserialized object read from the variable's byte column is not a String[]. The type validates the shape of the stored payload before casting, raising ActivitiIllegalArgumentException identifying the unexpected object.","triggerScenarios":"Reading a JPA entity list variable whose byte payload was written by a different variable type or an older engine format; corrupted/hand-edited ACT_GE_BYTEARRAY content; a custom serializer stored a different object type.","commonSituations":"Engine upgrade where the variable storage format changed; variables written by custom code directly into the byte array table; mixing single-entity and list variable types on the same variable name.","solutions":["Verify the variable was created by JPAEntityListVariableType (check TYPE_ column in ACT_GE_BYTEARRAY / variable table)","Delete and re-create the corrupted variable with correct entity list data","Check for engine version mismatch between write and read nodes in a cluster","Write a data migration for variables stored in the old format"],"exampleFix":"// before\n// variable bytes contain ArrayList, list type expects String[]\nObject read = in.readObject(); // ArrayList -> throws\n// after\nif (read instanceof String[]) {\n    return (String[]) read;\n}\n// or migrate: rewrite variable as proper JPA entity list","handlingStrategy":"validation","validationCode":"// detect legacy/mismatched variable payloads before reading\nString type = variable.getType().getTypeName();\nif (!\"jpa-entity-list\".equals(type)) {\n    throw new IllegalStateException(\"Variable \" + variable.getName() + \" is not a jpa-entity-list: \" + type);\n}","typeGuard":"Object read = in.readObject();\nif (read instanceof String[]) {\n    String[] ids = (String[]) read;\n}","tryCatchPattern":"try {\n    Object orders = runtimeService.getVariable(executionId, \"orders\");\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Deserialized value is not an array of ID's\")) {\n        // migrate or re-create the variable\n    }\n    throw e;\n}","preventionTips":["Run identical engine versions on all cluster nodes sharing the DB","Never hand-edit ACT_GE_BYTEARRAY contents","Migrate variables after engine format changes"],"tags":["jpa","deserialization","variables","activiti"],"backgroundTag":"unexpected-response-shape","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"}