{"record":{"id":"73242019d32be5bc","repo":"apache/beam","slug":"there-are-no-more-rows","errorCode":null,"errorMessage":"There are no more Rows.","messagePattern":"There are no more Rows\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/arrow/src/main/java/org/apache/beam/sdk/extensions/arrow/ArrowConversion.java","lineNumber":586,"sourceCode":"          new CachingFactory<>(\n              FieldVectorListValueGetterFactory.of(vectorSchemaRoot.getFieldVectors()));\n      this.currRowIndex = 0;\n    }\n\n    @Override\n    public void close() {\n      this.vectorSchemaRoot.close();\n    }\n\n    @Override\n    public boolean hasNext() {\n      return currRowIndex < vectorSchemaRoot.getRowCount();\n    }\n\n    @Override\n    public Row next() {\n      if (!hasNext()) {\n        throw new IllegalStateException(\"There are no more Rows.\");\n      }\n      Row result =\n          Row.withSchema(schema)\n              .withFieldValueGetters(\n                  this.fieldValueGetters, this.currRowIndex, TypeDescriptor.of(Integer.class));\n      this.currRowIndex += 1;\n      return result;\n    }\n  }\n\n  private ArrowConversion() {}\n\n  /** Converts Arrow schema to Beam row schema. */\n  public static class ArrowSchemaTranslator {\n\n    /** Converts a supported Beam row schema to an Arrow schema. */\n    public static org.apache.arrow.vector.types.pojo.Schema toArrowSchema(Schema schema) {\n      return new org.apache.arrow.vector.types.pojo.Schema(","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/arrow/src/main/java/org/apache/beam/sdk/extensions/arrow/ArrowConversion.java#L568-L604","documentation":"RecordBatchRowIterator.next() checks hasNext() (currRowIndex < vectorSchemaRoot.getRowCount()) and throws IllegalStateException if no rows remain. This guards Iterator contract violations: calling next() past the end of the current batch instead of checking hasNext first.","triggerScenarios":"Calling next() on the iterator when all rows in the current VectorSchemaRoot have been consumed; loops that call next() rowCount+1 times; iterators reused across batches without checking hasNext per batch.","commonSituations":"Hand-rolled row consumption without an Iterator wrapper; code that assumed more batches would be loaded before the iterator was exhausted; off-by-one in batch-size calculations.","solutions":["Always guard with hasNext() before next(), or consume via a for-each/Iterator loop","Fix loop bounds to use vectorSchemaRoot.getRowCount() / iterator.hasNext() rather than assumed sizes","Check whether upstream code stopped loading further RecordBatches early and load the next batch before continuing","Catch IllegalStateException at the boundary as a programming-bug signal and fix the caller rather than suppress it"],"exampleFix":"// before\nwhile (true) { Row r = it.next(); } // throws at end\n// after\nwhile (it.hasNext()) { Row r = it.next(); ... }","handlingStrategy":"try-catch","validationCode":"if (iterator.hasNext()) {\n  Row r = iterator.next();\n}","typeGuard":"java.util.Iterator<Row> it = ...;\nboolean canAdvance = it.hasNext();","tryCatchPattern":"try {\n  Row r = iterator.next();\n} catch (IllegalStateException e) {\n  // iterator exhausted: fix caller to check hasNext(); treat as bug, do not retry\n  throw new AssertionError(\"next() called past end of Arrow batch\", e);\n}","preventionTips":["Always iterate with hasNext() or for-each instead of bare next() calls","Never assume batch row counts; derive loop bounds from getRowCount()/hasNext()","Wrap the iterator in a well-tested collector (e.g. Iterators.concat) rather than manual loops"],"tags":["java","apache-beam","arrow","iterator"],"backgroundTag":"invalid-state-transition","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}