{"record":{"id":"2a0754b573f62044","repo":"apache/iceberg","slug":"not-a-primitive","errorCode":null,"errorMessage":"Not a primitive: ","messagePattern":"Not a primitive: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/variants/VariantValue.java","lineNumber":42,"sourceCode":"public interface VariantValue {\n  /** Returns the {@link PhysicalType} of this value. */\n  PhysicalType type();\n\n  /** Returns the serialized size in bytes of this value. */\n  int sizeInBytes();\n\n  /**\n   * Writes this value to the buffer at the given offset, ignoring the buffer's position and limit.\n   */\n  int writeTo(ByteBuffer buffer, int offset);\n\n  /**\n   * Returns this value as a {@link VariantPrimitive}.\n   *\n   * @throws IllegalArgumentException if the value is not a primitive\n   */\n  default VariantPrimitive<?> asPrimitive() {\n    throw new IllegalArgumentException(\"Not a primitive: \" + this);\n  }\n\n  /**\n   * Returns this value as a {@link VariantObject}.\n   *\n   * @throws IllegalArgumentException if the value is not an object\n   */\n  default VariantObject asObject() {\n    throw new IllegalArgumentException(\"Not an object: \" + this);\n  }\n\n  /**\n   * Returns this value as a {@link VariantArray}.\n   *\n   * @throws IllegalArgumentException if the value is not an array\n   */\n  default VariantArray asArray() {\n    throw new IllegalArgumentException(\"Not an array: \" + this);","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/variants/VariantValue.java#L24-L60","documentation":"VariantValue.asPrimitive() is a default downcast helper; the base interface's implementation always throws this IllegalArgumentException because only VariantPrimitive instances are primitives. It signals a caller assumed a value was a primitive when it is an object or array.","triggerScenarios":"Calling asPrimitive() on a VariantValue that is actually a VariantObject or VariantArray (e.g. after VariantValue.from without checking basicType), from code paths like castTo, buffer, decimalValue, or sanitizeVariant operating on non-primitive values.","commonSituations":"Assuming a variant field holds a scalar when it actually holds nested data; schema changed so a previously-primitive column now stores objects/arrays; missing isPrimitive()/type() check before downcasting.","solutions":["Check value.type() / basic type is PRIMITIVE before calling asPrimitive()","Handle the object/array cases explicitly in the calling code","Catch IllegalArgumentException from asPrimitive() and branch accordingly"],"exampleFix":"// before\nVariantPrimitive<?> p = value.asPrimitive();\n// after\nif (value instanceof VariantPrimitive) {\n  VariantPrimitive<?> p = (VariantPrimitive<?>) value;\n} else {\n  // handle object/array case\n}","handlingStrategy":"type-guard","validationCode":"if (!(value instanceof VariantPrimitive)) {\n  throw new IllegalStateException(\"expected primitive variant, got \" + value.type());\n}","typeGuard":"if (value instanceof VariantPrimitive) { VariantPrimitive<?> p = (VariantPrimitive<?>) value; }","tryCatchPattern":"try {\n  VariantPrimitive<?> p = value.asPrimitive();\n} catch (IllegalArgumentException e) {\n  // handle object/array case\n}","preventionTips":["Always check basicType() before downcasting VariantValue","Model the possibility of nested values in schema expectations","Prefer instanceof checks over default downcast helpers"],"tags":["variants","type-cast","downcast"],"backgroundTag":"type-mismatch","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"}