{"record":{"id":"d3cbade5481010b3","repo":"quarkusio/quarkus","slug":"cannot-create-new-deferredarraystoreparameter-afte","errorCode":null,"errorMessage":"Cannot create new DeferredArrayStoreParameter after array has been allocated","messagePattern":"Cannot create new DeferredArrayStoreParameter after array has been allocated","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java","lineNumber":2105,"sourceCode":"            }\n        }\n\n        void doPrepare(MethodContext context) {\n        }\n    }\n\n    abstract class DeferredArrayStoreParameter extends DeferredParameter {\n\n        int arrayIndex = -1;\n        final String returnType;\n        ResultHandle originalResultHandle;\n        ResultHandle originalArrayResultHandle;\n        MethodCreator originalRhMethod;\n\n        DeferredArrayStoreParameter(String expectedType) {\n            returnType = expectedType;\n            if (loadComplete) {\n                throw new RuntimeException(\"Cannot create new DeferredArrayStoreParameter after array has been allocated\");\n            }\n        }\n\n        DeferredArrayStoreParameter(Object target, Class<?> expectedType) {\n            if (expectedType == List.class || expectedType == Map.class || expectedType == Set.class\n                    || expectedType == SortedMap.class || expectedType == SortedSet.class) {\n                returnType = expectedType.getName();\n            } else if (target != null && !(target instanceof Proxy) && isAccessible(target.getClass())) {\n                returnType = target.getClass().getName();\n            } else if (expectedType != null && isAccessible(expectedType)) {\n                returnType = expectedType.getName();\n            } else {\n                returnType = null;\n            }\n            if (loadComplete) {\n                throw new RuntimeException(\"Cannot create new DeferredArrayStoreParameter after array has been allocated\");\n            }\n        }","sourceCodeStart":2087,"sourceCodeEnd":2123,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java#L2087-L2123","documentation":"DeferredArrayStoreParameter represents array/collection elements that are filled into an allocated array or collection at a later point in generated bytecode. Once the array has been allocated (loadComplete == true) no new deferred store parameter may be created for it, since the allocation already happened in the generated method.","triggerScenarios":"Creating a DeferredArrayStoreParameter with the single-arg (expectedType) constructor after the recording of the array/collection has already been finalized — i.e. element recording interleaved incorrectly with the array build phase inside BytecodeRecorderImpl's serialization logic.","commonSituations":"Usually internal: triggered by extension code that records mutable collections/lists in an order the serializer does not expect (e.g. mutating a recorded List while it is being serialized), or custom ObjectSerializer implementations that add elements late.","solutions":["Do not mutate the recorded collection/array after passing it to the recorder or after serialization begins","Snapshot collections before recording (record an immutable copy: List.copyOf(...))","If a custom ObjectSerializer is involved, ensure all elements are created before the array allocation step","Report/upgrade: verify Quarkus version consistency between core and extensions"],"exampleFix":"// before\nList<String> list = new ArrayList<>();\nrecorderMethod.returnValue(list); // list mutated afterwards during recording\nlist.add(\"late\");\n// after\nList<String> list = List.copyOf(sourceList); // snapshot, never mutated\nrecorderMethod.returnValue(list);","handlingStrategy":"validation","validationCode":"static <T> List<T> frozen(List<T> in) {\n    return List.copyOf(in); // snapshot before recording; never mutate after\n}","typeGuard":null,"tryCatchPattern":"try {\n    recorder.returnValue(collection);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"after array has been allocated\")) {\n        throw new IllegalStateException(\"Collection mutated during recording; pass an immutable snapshot\", e);\n    }\n    throw e;\n}","preventionTips":["Never mutate a collection after passing it to the recorder","Record immutable copies (List.copyOf, Map.copyOf)","Keep recorded objects local and single-threaded"],"tags":["build-time","bytecode-recorder","serialization","quarkus-extension"],"backgroundTag":"deferred-array-store-after-allocation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}