{"record":{"id":"d7d03bc2cf29328f","repo":"apache/pulsar","slug":"avro-record-builder-doesn-t-support-non-avro-recor","errorCode":null,"errorMessage":"Avro Record Builder doesn't support non-avro record as a field","messagePattern":"Avro Record Builder doesn't support non-avro record as a field","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/generic/AvroRecordBuilderImpl.java","lineNumber":53,"sourceCode":"        this.genericSchema = genericSchema;\n        this.avroRecordBuilder =\n            new org.apache.avro.generic.GenericRecordBuilder(genericSchema.getAvroSchema());\n    }\n\n    /**\n     * Sets the value of a field.\n     *\n     * @param fieldName the name of the field to set.\n     * @param value the value to set.\n     * @return a reference to the RecordBuilder.\n     */\n    @Override\n    public GenericRecordBuilder set(String fieldName, Object value) {\n        if (value instanceof GenericRecord) {\n            if (value instanceof GenericAvroRecord) {\n                avroRecordBuilder.set(fieldName, ((GenericAvroRecord) value).getAvroRecord());\n            } else {\n                throw new IllegalArgumentException(\"Avro Record Builder doesn't support non-avro record as a field\");\n            }\n        } else {\n            avroRecordBuilder.set(fieldName, value);\n        }\n        return this;\n    }\n\n    /**\n     * Sets the value of a field.\n     *\n     * @param field the field to set.\n     * @param value the value to set.\n     * @return a reference to the RecordBuilder.\n     */\n    @Override\n    public GenericRecordBuilder set(Field field, Object value) {\n        set(field.getIndex(), value);\n        return this;","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/generic/AvroRecordBuilderImpl.java#L35-L71","documentation":"AvroRecordBuilderImpl.set(String, Object) accepts a nested record value only if it is a GenericAvroRecord (the Avro-backed GenericRecord implementation). If the value is a GenericRecord but of another implementation (e.g. GenericJsonRecord), the builder cannot convert it to an Avro record and throws IllegalArgumentException.","triggerScenarios":"Calling RecordBuilder.set(fieldName, value) where value instanceof GenericRecord but not instanceof GenericAvroRecord — typically passing a GenericJsonRecord or a custom GenericRecord implementation into an Avro record builder.","commonSituations":"Mixing generic schema types across topics: reading a JSON-schema topic with generic schemas and writing the record as a field of an AVRO-schema message; copying fields between records decoded with different generic schema backends.","solutions":["Convert the value to an Avro record first (e.g. use Avro's DatumReader/Writer or decode with the matching Avro generic schema)","Use a GenericAvroRecord for nested fields when building AVRO records","Ensure the nested field's schema type matches the parent record's schema type (AVRO parent -> AVRO child)","If records genuinely differ in type, build the nested Avro record from the JSON node via schema mapping"],"exampleFix":"// before\nbuilder.set(\"nestedField\", genericJsonRecord); // IllegalArgumentException\n// after\nGenericAvroRecord avroNested = (GenericAvroRecord) avroSchemaReader.read(jsonRecordToBytes(genericJsonRecord));\nbuilder.set(\"nestedField\", avroNested);","handlingStrategy":"type-guard","validationCode":"if (value instanceof GenericRecord && !(value instanceof GenericAvroRecord)) {\n    throw new IllegalArgumentException(\"Convert nested record to GenericAvroRecord before setting on an Avro builder\");\n}","typeGuard":"boolean isAvroGenericRecord(Object v) {\n    return !(v instanceof GenericRecord) || v instanceof GenericAvroRecord;\n}","tryCatchPattern":"try {\n    builder.set(fieldName, value);\n} catch (IllegalArgumentException e) {\n    GenericAvroRecord converted = convertToAvroRecord((GenericRecord) value);\n    builder.set(fieldName, converted);\n}","preventionTips":["Use GenericAvroSchema for all nested record fields of AVRO topics","Never mix GenericJsonRecord into Avro record builders","Decode nested fields with the same schema backend as the parent","Add a unit test that builds records with nested values from each schema type"],"tags":["pulsar","avro","schema","type-mismatch"],"backgroundTag":"avro-record-type-mismatch","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}