{"record":{"id":"580191355d206090","repo":"apache/flink","slug":"please-use-avroparquetreaders-forspecificrecord-cl","errorCode":null,"errorMessage":"Please use AvroParquetReaders.forSpecificRecord(Class<T>) for SpecificRecord.","messagePattern":"Please use AvroParquetReaders\\.forSpecificRecord\\(Class<T>\\) for SpecificRecord\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/avro/AvroParquetReaders.java","lineNumber":72,"sourceCode":"                new AvroTypeInfo<>(typeClass), () -> SpecificData.get());\n    }\n\n    /**\n     * Creates a new {@link AvroParquetRecordFormat} that reads the parquet file into Avro records\n     * via reflection.\n     *\n     * <p>To read into Avro {@link GenericRecord GenericRecords}, use the {@link\n     * #forGenericRecord(Schema)} method.\n     *\n     * <p>To read into Avro {@link org.apache.avro.specific.SpecificRecord SpecificRecords}, use the\n     * {@link #forSpecificRecord(Class)} method.\n     *\n     * @see #forGenericRecord(Schema)\n     * @see #forSpecificRecord(Class)\n     */\n    public static <T> StreamFormat<T> forReflectRecord(final Class<T> typeClass) {\n        if (SpecificRecordBase.class.isAssignableFrom(typeClass)) {\n            throw new IllegalArgumentException(\n                    \"Please use AvroParquetReaders.forSpecificRecord(Class<T>) for SpecificRecord.\");\n        } else if (GenericRecord.class.isAssignableFrom(typeClass)) {\n            throw new IllegalArgumentException(\n                    \"Please use AvroParquetReaders.forGenericRecord(Class<T>) for GenericRecord.\"\n                            + \"Cannot read and create Avro GenericRecord without specifying the Avro Schema. \"\n                            + \"This is because Flink needs to be able serialize the results in its data flow, which is\"\n                            + \"very inefficient without the schema. And while the Schema is stored in the Avro file header,\"\n                            + \"Flink needs this schema during 'pre-flight' time when the data flow is set up and wired,\"\n                            + \"which is before there is access to the files\");\n        }\n\n        // this is a PoJo that Avo will reader via reflect de-serialization\n        // for Flink, this is just a plain PoJo type\n        return new AvroParquetRecordFormat<>(\n                TypeExtractor.createTypeInfo(typeClass), () -> ReflectData.get());\n    }\n\n    /**","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/avro/AvroParquetReaders.java#L54-L90","documentation":"AvroParquetReaders.forReflectRecord(Class) refuses classes that extend SpecificRecordBase. Specific (generated) Avro classes must go through forSpecificRecord(Class) because their schema is available from the generated class itself, not via reflection-based POJO extraction.","triggerScenarios":"Calling AvroParquetReaders.forReflectRecord(MyGeneratedAvroRecord.class) where MyGeneratedAvroRecord extends org.apache.avro.specific.SpecificRecordBase (i.e., a class generated by avro-maven-plugin / avsc codegen).","commonSituations":"A codebase mixes hand-written POJOs and Avro-generated records; a developer passes the generated class to the generic reflection API by mistake, or an IDE auto-completes forReflectRecord.","solutions":["Use AvroParquetReaders.forSpecificRecord(MyGeneratedRecord.class) for avro-generated classes","Use AvroParquetReaders.forReflectRecord(MyPojo.class) only for plain POJOs without Avro base classes","Use forGenericRecord(Schema) when you want schema-driven generic records"],"exampleFix":"// before\nStreamFormat<MyRecord> f = AvroParquetReaders.forReflectRecord(MyRecord.class); // MyRecord extends SpecificRecordBase\n\n// after\nStreamFormat<MyRecord> f = AvroParquetReaders.forSpecificRecord(MyRecord.class);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static <T> StreamFormat<T> avroFormat(Class<T> cls) {\n  if (SpecificRecordBase.class.isAssignableFrom(cls)) return AvroParquetReaders.forSpecificRecord(cls.asSubclass(SpecificRecordBase.class).cast(null) == null ? cls : cls); // specific\n  if (GenericRecord.class.isAssignableFrom(cls)) throw new IllegalArgumentException(\"need Schema\");\n  return AvroParquetReaders.forReflectRecord(cls);\n}","tryCatchPattern":null,"preventionTips":["Route generated avro classes to forSpecificRecord, POJOs to forReflectRecord","Keep a single factory helper that picks the API by type","Watch for the mirrored GenericRecord check right after this one"],"tags":["parquet","avro","api-misuse","flink"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}