{"record":{"id":"668af1a62e026db5","repo":"apache/iceberg","slug":"invalid-primitive-type-for-decimal-primitivetyp","errorCode":null,"errorMessage":"Invalid primitive type for decimal: ${primitiveType}","messagePattern":"Invalid primitive type for decimal: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/VariantWriterBuilder.java","lineNumber":232,"sourceCode":"              ParquetVariantWriters.decimal(\n                  ParquetValueWriters.decimalAsLong(\n                      desc, decimal.getPrecision(), decimal.getScale()),\n                  decimal.getPrecision(),\n                  decimal.getScale(),\n                  PhysicalType.DECIMAL8);\n          return Optional.of(writer);\n        case INT32:\n          writer =\n              ParquetVariantWriters.decimal(\n                  ParquetValueWriters.decimalAsInteger(\n                      desc, decimal.getPrecision(), decimal.getScale()),\n                  decimal.getPrecision(),\n                  decimal.getScale(),\n                  PhysicalType.DECIMAL4);\n          return Optional.of(writer);\n      }\n\n      throw new IllegalArgumentException(\n          \"Invalid primitive type for decimal: \" + desc.getPrimitiveType());\n    }\n\n    @Override\n    public Optional<ParquetValueWriter<?>> visit(DateLogicalTypeAnnotation ignored) {\n      ParquetValueWriter<VariantValue> writer =\n          ParquetVariantWriters.primitive(ParquetValueWriters.ints(desc), PhysicalType.DATE);\n      return Optional.of(writer);\n    }\n\n    @Override\n    public Optional<ParquetValueWriter<?>> visit(TimeLogicalTypeAnnotation time) {\n      ParquetValueWriter<VariantValue> writer =\n          ParquetVariantWriters.primitive(ParquetValueWriters.longs(desc), PhysicalType.TIME);\n      return Optional.of(writer);\n    }\n\n    @Override","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/VariantWriterBuilder.java#L214-L250","documentation":"Thrown by VariantWriterBuilder's decimal logical-type visitor when the typed_value column's physical primitive is not one of the decimal-capable primitives the writer supports (INT32/INT64, per the reader's DECIMAL4/DECIMAL8 mapping). The builder cannot create a decimal Variant writer for the given primitive type.","triggerScenarios":"visit(DecimalLogicalTypeAnnotation) where desc.getPrimitiveType() is neither of the supported decimal-backed primitives (e.g. FLBA/BINARY-backed decimal with high precision) while writing a shredded Variant.","commonSituations":"Shredding decimals with precision > 18 that default to fixed-length backing; schema propagation from engines that emit BINARY decimals; misconfigured shredding schemas.","solutions":["Restrict shredded decimals to precision that fits INT32 (<=9) or INT64 (<=18) and back them with those primitives.","Leave higher-precision decimals unshredded inside the Variant binary.","Adjust the shredding-schema derivation to exclude decimals that cannot be backed by INT32/INT64."],"exampleFix":"// before\nTypes.required(PrimitiveTypeName.BINARY).as(DecimalLogicalType.decimalType(38, 12)).named(\"typed_value\")\n\n// after\nTypes.required(PrimitiveTypeName.INT64).as(DecimalLogicalType.decimalType(18, 12)).named(\"typed_value\")","handlingStrategy":"validation","validationCode":"PrimitiveTypeName p = desc.getPrimitiveType().getPrimitiveTypeName();\nPreconditions.checkArgument(p == INT32 || p == INT64,\n    \"Decimal typed_value must be INT32/INT64-backed, got %s\", p);","typeGuard":"boolean isWritableShreddedDecimal(Types.NestedField f) {\n  return switch (f.type().typeId()) {\n    case DECIMAL d -> d.precision() <= 18;\n    default -> false;\n  };\n}","tryCatchPattern":"try {\n  buildVariantWriter(schema);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Invalid primitive type for decimal\")) {\n    excludeFromShredding(columnName);\n  } else throw e;\n}","preventionTips":["Cap shredded decimal precision at 18 so INT64 backing suffices","Exclude wide decimals from shredding schemas at plan time","Verify physical backing type whenever decimal logical annotations are present"],"tags":["parquet","variant","decimal","shredding"],"backgroundTag":"invalid-argument-value","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"}