apache/iceberg · error · IllegalArgumentException

No column at position

Error message

No column at position ${colPos}

What it means

PositionDelete models a row as a 3-element struct: position 0 = file path, 1 = position, 2 = the deleted row (nullable). get(colPos) throws IllegalArgumentException for any index outside 0..2, since there are only three logical columns.

Solutions

  1. Only use colPos values 0, 1, or 2; access row fields through the row object (a StructLike or row type) instead
  2. Bounds-check colPos against the logical arity of 3 before calling get
  3. If iterating generically, cap iteration at PositionDelete's size (3)
  4. For row-level columns, cast get(2) to the row type and index into that

Example fix

// before
for (int i = 0; i < schema.columns().size(); i++) {
  Object v = positionDelete.get(i); // throws at i >= 3
}
// after
Object path = positionDelete.get(0);
Long pos = positionDelete.get(1);
R row = positionDelete.get(2); // access row fields via row
Defensive patterns

Strategy: validation

Validate before calling

if (colPos < 0 || colPos > 2) {
  throw new IllegalArgumentException("PositionDelete has only 3 columns (0=path, 1=pos, 2=row)");
}

Type guard

static boolean isValidColumn(int colPos) {
  return colPos >= 0 && colPos <= 2;
}

Try / catch

try {
  return positionDelete.get(colPos);
} catch (IllegalArgumentException e) {
  throw new IllegalArgumentException("colPos must be 0-2 for PositionDelete", e);
}

Prevention

When it happens

Trigger: Calling PositionDelete.get(3) or higher (or negative), e.g. when generic struct-like access code iterates a schema with more columns than PositionDelete actually has.

Common situations: Generic readers projecting a table schema's column count onto a PositionDelete instance; off-by-one loops over columns; assuming the row struct's fields are addressable directly via get().

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/36a37cd48c403002. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/deletes/PositionDelete.java:70

    return path;
  }

  public long pos() {
    return pos;
  }

  @Override
  @SuppressWarnings("unchecked")
  public <T> T get(int colPos, Class<T> javaClass) {
    switch (colPos) {
      case 0:
        return (T) path;
      case 1:
        return (T) (Long) pos;
      case 2:
        return (T) row;
      default:
        throw new IllegalArgumentException("No column at position " + colPos);
    }
  }

  @Override
  public <T> void set(int colPos, T value) {
    switch (colPos) {
      case 0:
        this.path = (CharSequence) value;
        break;
      case 1:
        this.pos = (Long) value;
        break;
      case 2:
        this.row = (R) value;
        break;
      default:
        throw new IllegalArgumentException("No column at position " + colPos);
    }

View on GitHub (pinned to 86d9c8fc54)