{"record":{"id":"3cf08163bf5cfeef","repo":"apache/iceberg","slug":"unknown-field-ordinal","errorCode":null,"errorMessage":"Unknown field ordinal: ","messagePattern":"Unknown field ordinal: ","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/DeletionVectorStruct.java","lineNumber":120,"sourceCode":"\n  @Override\n  public DeletionVectorStruct copy() {\n    return new DeletionVectorStruct(this);\n  }\n\n  @Override\n  protected <T> T internalGet(int pos, Class<T> javaClass) {\n    return javaClass.cast(getByPos(pos));\n  }\n\n  private Object getByPos(int pos) {\n    return switch (pos) {\n      case 0 -> location;\n      case 1 -> offset;\n      case 2 -> sizeInBytes;\n      case 3 -> cardinality;\n      case 4 -> keyMetadata();\n      default -> throw new UnsupportedOperationException(\"Unknown field ordinal: \" + pos);\n    };\n  }\n\n  @Override\n  protected <T> void internalSet(int pos, T value) {\n    switch (pos) {\n        // always coerce to String for Serializable\n      case 0 -> this.location = value.toString();\n      case 1 -> this.offset = (Long) value;\n      case 2 -> this.sizeInBytes = (Long) value;\n      case 3 -> this.cardinality = (Long) value;\n      case 4 -> this.keyMetadata = ByteBuffers.toByteArray((ByteBuffer) value);\n      default -> {\n        // ignore the object, it must be from a newer version of the format\n      }\n    }\n  }\n","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/DeletionVectorStruct.java#L102-L138","documentation":"DeletionVectorStruct.getByPos maps a fixed set of ordinals (0=location, 1=offset, 2=sizeInBytes, 3=cardinality, 4=keyMetadata) to struct field values. Any ordinal outside 0-4 triggers UnsupportedOperationException('Unknown field ordinal: ' + pos). This only happens if internal code requests a position that is not part of the deletion-vector struct schema, which normally cannot occur with a valid schema.","triggerScenarios":"Calling internalGet/getByPos with a position >= 5 or negative, typically when the struct is accessed with a schema that does not match the deletion vector type (e.g. a stale or hand-built Types.StructType whose field count exceeds the deletion vector's 5 fields).","commonSituations":"Custom readers projecting extra fields onto the DV struct; schema evolution code reusing a cached projection across different struct types; internal misuse after upgrading Iceberg where the DV struct layout changed.","solutions":["Verify the projection schema used to read the deletion vector struct contains exactly the 5 DV fields; regenerate the projection rather than reusing a cached one.","Log the offending `pos` value and compare against the DV struct type (`MetadataTableType`/DeletionVector schema) to find the mismatched accessor.","If you wrote custom accessor code, index fields by name via the schema instead of hard-coded ordinals."],"exampleFix":"// before: positional access with a hand-built schema\nObject v = dvStruct.get(pos, Object.class); // pos from arbitrary schema\n// after: look up the ordinal from the actual DV schema\nint pos = deletionVectorType.field(field.name()).fieldId() - firstFieldId;\nObject v = dvStruct.get(pos, Object.class);","handlingStrategy":"type-guard","validationCode":"if (pos < 0 || pos >= deletionVectorType.fields().size()) {\n  throw new IllegalArgumentException(\"Invalid DV ordinal: \" + pos);\n}","typeGuard":"boolean isValidDvOrdinal(int pos) { return pos >= 0 && pos <= 4; }","tryCatchPattern":"try {\n  Object v = dvStruct.get(pos, Object.class);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().startsWith(\"Unknown field ordinal\")) {\n    // projection/schema mismatch: rebuild the projection from the DV type\n  } else throw e;\n}","preventionTips":["Derive struct ordinals from Types.StructType.fields() lookups, never hardcoded integers.","Rebuild projections after Iceberg upgrades instead of reusing serialized/cached schemas.","Keep projections restricted to the 5 deletion-vector fields."],"tags":["struct","ordinal","unsupported-operation","schema"],"backgroundTag":"unsupported-operation","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"}