{"record":{"id":"b40fddb1bb5102e6","repo":"apache/iceberg","slug":"not-a-boolean-column","errorCode":null,"errorMessage":"Not a boolean column","messagePattern":"Not a boolean column","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/TripleIterator.java","lineNumber":55,"sourceCode":"   *\n   * <p>This method does not advance this iterator.\n   *\n   * @return the repetition level of the current triple, or 0 if there is no current triple.\n   * @throws java.util.NoSuchElementException if there are no more elements\n   */\n  int currentRepetitionLevel();\n\n  /**\n   * Returns the next value as an un-boxed boolean.\n   *\n   * <p>This method has the same behavior as {@link #next()} and will advance this iterator.\n   *\n   * @return the next value as an un-boxed boolean\n   * @throws java.util.NoSuchElementException if there are no more elements\n   * @throws UnsupportedOperationException if the underlying data values are not booleans\n   */\n  default boolean nextBoolean() {\n    throw new UnsupportedOperationException(\"Not a boolean column\");\n  }\n\n  /**\n   * Returns the next value as an un-boxed int.\n   *\n   * <p>This method has the same behavior as {@link #next()} and will advance this iterator.\n   *\n   * @return the next value as an un-boxed int\n   * @throws java.util.NoSuchElementException if there are no more elements\n   * @throws UnsupportedOperationException if the underlying data values are not ints\n   */\n  default int nextInteger() {\n    throw new UnsupportedOperationException(\"Not an integer column\");\n  }\n\n  /**\n   * Returns the next value as an un-boxed long.\n   *","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/TripleIterator.java#L37-L73","documentation":"TripleIterator.nextBoolean() is a default method on the page-level column iterator interface that intentionally throws UnsupportedOperationException; only concrete iterators for boolean columns (e.g. PageIterator built for BOOLEAN_LE/BOOLEAN physical types) override it. Hitting this message means a typed accessor was called on an iterator whose underlying Parquet column is not a boolean — an internal type-dispatch bug, not a user data error.","triggerScenarios":"Calling nextBoolean() on a TripleIterator whose column descriptor's primitive type is not BOOLEAN, e.g. a custom ParquetValueReader or materializer that dispatches on the wrong Iceberg type id so a non-boolean column routes to the boolean reader.","commonSituations":"Custom read type converters (GenericParquetReaders / user-supplied ParquetValueReaders) mapping an Iceberg type to the wrong physical Parquet type; schema mismatch between the Iceberg projection and the actual file schema after an unenforced type promotion; bespoke column iterators in extension code.","solutions":["Check the reader/materializer dispatch for that column: the Iceberg type must map to Parquet BOOLEAN for nextBoolean()","Verify the projected Iceberg schema matches the actual file schema (types were not altered/renamed)","Do not call nextBoolean() directly on a TripleIterator unless its ColumnDescriptor primitive type is BOOLEAN","Update to a recent Iceberg version if a bundled type-mapping bug dispatched the wrong reader","For custom ParquetValueReaders, use TripleIterator.next()/a correctly typed reader instead of hard-coding the accessor"],"exampleFix":"// before: boolean reader bound to a non-boolean column\ncase INT: return new IntegerReader(...); // wrong dispatch\n\n// after: dispatch on the physical primitive type\ncase BOOLEAN: return new BooleanReader(desc);\ncase INT32: return new IntegerReader(desc);","handlingStrategy":"type-guard","validationCode":"if (desc.getPrimitiveType().getPrimitiveTypeName() != PrimitiveTypeName.BOOLEAN) {\n  throw new IllegalArgumentException(\"Column \" + desc + \" is not BOOLEAN\");\n}","typeGuard":"boolean isBooleanColumn(ColumnDescriptor desc) {\n  return desc.getPrimitiveType().getPrimitiveTypeName() == PrimitiveTypeName.BOOLEAN;\n}","tryCatchPattern":"try { v = iterator.nextBoolean(); } catch (UnsupportedOperationException e) { throw new IllegalStateException(\"Reader/column type dispatch mismatch: \" + desc, e); }","preventionTips":["Dispatch value readers on the Parquet physical type, not the Iceberg type alone","Validate that projected schema types match the file's footer schema","Avoid calling typed accessors on TripleIterator directly from application code","Cover custom ParquetValueReaders with tests on every physical type"],"tags":["parquet","type-mismatch","column-iterator"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}