{"record":{"id":"af8131e0bd914225","repo":"apache/flink","slug":"could-not-instantiate-record","errorCode":null,"errorMessage":"Could not instantiate record","messagePattern":"Could not instantiate record","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/JavaRecordBuilderFactory.java","lineNumber":91,"sourceCode":"\n    /** Builder class for incremental record construction. */\n    @Internal\n    final class JavaRecordBuilder {\n        private final Object[] args;\n\n        JavaRecordBuilder() {\n            if (defaultConstructorArgs == null) {\n                args = new Object[canonicalConstructor.getParameterCount()];\n            } else {\n                args = Arrays.copyOf(defaultConstructorArgs, defaultConstructorArgs.length);\n            }\n        }\n\n        T build() {\n            try {\n                return canonicalConstructor.newInstance(args);\n            } catch (Exception e) {\n                throw new RuntimeException(\"Could not instantiate record\", e);\n            }\n        }\n\n        /**\n         * Set record field by index. If parameter index mapping is provided, the index is mapped,\n         * otherwise it is used as is.\n         *\n         * @param i index of field to be set\n         * @param value field value\n         */\n        void setField(int i, Object value) {\n            if (paramIndexMapping != null) {\n                args[paramIndexMapping[i]] = value;\n            } else {\n                args[i] = value;\n            }\n        }\n    }","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/JavaRecordBuilderFactory.java#L73-L109","documentation":"Thrown when JavaRecordBuilderFactory.build() cannot invoke a Java record's canonical constructor via Constructor.newInstance(). The RuntimeException wraps the reflective cause, which can be illegal access (non-public record), wrong argument count/types (schema evolution remapping mismatch), or an exception thrown by the record's compact constructor itself.","triggerScenarios":"Deserializing or copying a Java record through Kryo/POJO serialization paths (e.g. KryoSerializer or PojoSerializer reading a record): canonicalConstructor.newInstance(args) throws IllegalAccessException, IllegalArgumentException, or InvocationTargetException; also when argIndexMapping from schema migration feeds mis-typed values.","commonSituations":"Record class is package-private or nested without being accessible to the user-code classloader; record read from a savepoint/checkpoint written with a different record layout (added/removed/reordered components); record compact constructor validates and throws on restored default values; user-code classloader isolation between the serializer and the record class.","solutions":["Inspect the wrapped cause in the stack trace (e.getCause()) - it names the real failure: access, argument mismatch, or constructor exception","Make the record class public (top-level or a public nested type) so the canonical constructor is invocable","If restoring old state, verify the record's component names/types match what the serializer snapshot expects, or realign fields so argIndexMapping is correct","Fix the record's compact constructor if it rejects valid default values for newly added components"],"exampleFix":"// before: package-private record\nrecord Event(String id, long ts) {}\n\n// after: public record\npublic record Event(String id, long ts) {}","handlingStrategy":"validation","validationCode":"if (!Modifier.isPublic(recordClass.getModifiers())) {\n    throw new IllegalArgumentException(\"Record class must be public: \" + recordClass);\n}\nif (!recordClass.isRecord()) {\n    throw new IllegalArgumentException(\"Not a record: \" + recordClass);\n}","typeGuard":"static boolean isInstantiableRecord(Class<?> c) {\n    if (!c.isRecord() || !Modifier.isPublic(c.getModifiers())) {\n        return false;\n    }\n    try {\n        c.getDeclaredConstructor().setAccessible(true);\n        return true;\n    } catch (ReflectiveOperationException | RuntimeException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    T value = builder.build();\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause(); // IllegalAccessException | InvocationTargetException | IllegalArgumentException\n    throw new IllegalStateException(\"Record instantiation failed: \" + cause, cause);\n}","preventionTips":["Keep record classes public and their component types stable across job upgrades","Unit-test serializer round-trips for every record type used in state","Avoid compact-constructor validation that rejects restored default values"],"tags":["serialization","records","reflection","kryo"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}