{"record":{"id":"395f86858357f9ac","repo":"apache/iceberg","slug":"cannot-read-without-at-least-one-projected-column","errorCode":null,"errorMessage":"Cannot read without at least one projected column","messagePattern":"Cannot read without at least one projected column","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"arrow/src/main/java/org/apache/iceberg/arrow/vectorized/ArrowReader.java","lineNumber":246,"sourceCode":"        FileIO io,\n        EncryptionManager encryptionManager,\n        boolean caseSensitive,\n        int batchSize,\n        boolean reuseContainers) {\n      List<FileScanTask> fileTasks =\n          StreamSupport.stream(tasks.spliterator(), false)\n              .map(CombinedScanTask::files)\n              .flatMap(Collection::stream)\n              .collect(Collectors.toList());\n      this.fileItr = fileTasks.iterator();\n\n      if (fileTasks.stream().anyMatch(TableScanUtil::hasDeletes)) {\n        throw new UnsupportedOperationException(\n            \"Cannot read files that require applying delete files\");\n      }\n\n      if (expectedSchema.columns().isEmpty()) {\n        throw new UnsupportedOperationException(\n            \"Cannot read without at least one projected column\");\n      }\n\n      Set<TypeID> unsupportedTypes =\n          Sets.difference(\n              expectedSchema.columns().stream()\n                  .map(c -> c.type().typeId())\n                  .collect(Collectors.toSet()),\n              SUPPORTED_TYPES);\n      if (!unsupportedTypes.isEmpty()) {\n        throw new UnsupportedOperationException(\n            \"Cannot read unsupported column types: \" + unsupportedTypes);\n      }\n\n      Map<String, ByteBuffer> keyMetadata = Maps.newHashMap();\n      fileTasks.stream()\n          .map(FileScanTask::file)\n          .forEach(file -> keyMetadata.put(file.location(), file.keyMetadata()));","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/arrow/src/main/java/org/apache/iceberg/arrow/vectorized/ArrowReader.java#L228-L264","documentation":"The VectorizedCombinedScanIterator constructor requires the projected schema to contain at least one column; an empty columns() list throws this UnsupportedOperationException. Vectorized batch reading is meaningless with zero projected columns, so the reader rejects it early.","triggerScenarios":"Constructing a VectorizedCombinedScanIterator with an expectedSchema whose columns() list is empty (e.g. scan selecting no columns, or an all-filtered projection).","commonSituations":"Count-only scans or metadata-style queries accidentally routed through the vectorized Arrow reader; programmatic scans built with an empty projection.","solutions":["Project at least one column in the scan schema before reading.","Use metadata/table APIs (row counts, snapshot summaries) instead of a zero-column data scan for count-only workloads.","Fall back to the non-vectorized reader path that tolerates empty projections."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"Preconditions.checkArgument(!expectedSchema.columns().isEmpty(), \"At least one column must be projected\");","typeGuard":"static boolean hasProjection(Schema s) { return !s.columns().isEmpty(); }","tryCatchPattern":"try { return new VectorizedCombinedScanIterator(...); } catch (UnsupportedOperationException e) { return emptyOrMetadataResult(...); }","preventionTips":["Always project at least one column before vectorized scans","Use snapshot metadata summaries for count-only queries"],"tags":["java","arrow","vectorized-read","empty-schema"],"backgroundTag":"empty-required-field","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}