{"record":{"id":"1d3f1637f0766ffa","repo":"apache/iceberg","slug":"cannot-create-writer-for-non-option-union-s","errorCode":null,"errorMessage":"Cannot create writer for non-option union: %s","messagePattern":"Cannot create writer for non-option union: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/avro/BaseWriteBuilder.java","lineNumber":48,"sourceCode":"\n  protected abstract ValueWriter<?> fixedWriter(int length);\n\n  @Override\n  public ValueWriter<?> record(Schema record, List<String> names, List<ValueWriter<?>> fields) {\n    return createRecordWriter(fields);\n  }\n\n  @Override\n  public ValueWriter<?> union(Schema union, List<ValueWriter<?>> options) {\n    Preconditions.checkArgument(\n        options.size() == 2, \"Cannot create writer for non-option union: %s\", union);\n    if (union.getTypes().get(0).getType() == Schema.Type.NULL) {\n      return ValueWriters.option(0, options.get(1));\n    } else if (union.getTypes().get(1).getType() == Schema.Type.NULL) {\n      return ValueWriters.option(1, options.get(0));\n    } else {\n      throw new IllegalArgumentException(\n          String.format(\"Cannot create writer for non-option union: %s\", union));\n    }\n  }\n\n  @Override\n  public ValueWriter<?> array(Schema array, ValueWriter<?> elementWriter) {\n    if (array.getLogicalType() instanceof LogicalMap) {\n      ValueWriters.StructWriter<?> keyValueWriter = (ValueWriters.StructWriter<?>) elementWriter;\n      return ValueWriters.arrayMap(keyValueWriter.writer(0), keyValueWriter.writer(1));\n    }\n\n    return ValueWriters.array(elementWriter);\n  }\n\n  @Override\n  public ValueWriter<?> map(Schema map, ValueWriter<?> valueWriter) {\n    return ValueWriters.map(ValueWriters.strings(), valueWriter);\n  }\n","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/avro/BaseWriteBuilder.java#L30-L66","documentation":"Validation in BaseWriteBuilder.union: an Avro union schema for an optional field must have exactly two branches (null + type) to map to Iceberg's optional model. The %s is the union schema; the check fails when the union has more (or fewer) than two types, i.e. the schema is not a nullable option.","triggerScenarios":"Thrown at core/src/main/java/org/apache/iceberg/avro/BaseWriteBuilder.java:48 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Rewrite the Avro schema so nullable fields are two-branch unions of null and the value type","Flatten multi-branch unions into separate optional fields before writing","Validate the schema shape before handing it to the Avro writer builder"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}