{"record":{"id":"946ec02e7238abfc","repo":"apache/iceberg","slug":"cannot-set-row-kind-in-the-rowdataprojection-946ec0","errorCode":null,"errorMessage":"Cannot set row kind in the RowDataProjection","messagePattern":"Cannot set row kind in the RowDataProjection","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/data/RowDataProjection.java","lineNumber":198,"sourceCode":"  private Object getValue(int pos) {\n    Preconditions.checkState(rowData != null, \"Row data not wrapped\");\n    return getters[pos].getFieldOrNull(rowData);\n  }\n\n  @Override\n  public int getArity() {\n    return getters.length;\n  }\n\n  @Override\n  public RowKind getRowKind() {\n    Preconditions.checkState(rowData != null, \"Row data not wrapped\");\n    return rowData.getRowKind();\n  }\n\n  @Override\n  public void setRowKind(RowKind kind) {\n    throw new UnsupportedOperationException(\"Cannot set row kind in the RowDataProjection\");\n  }\n\n  @Override\n  public boolean isNullAt(int pos) {\n    return getValue(pos) == null;\n  }\n\n  @Override\n  public boolean getBoolean(int pos) {\n    return (boolean) getValue(pos);\n  }\n\n  @Override\n  public byte getByte(int pos) {\n    return (byte) getValue(pos);\n  }\n\n  @Override","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/data/RowDataProjection.java#L180-L216","documentation":"RowDataProjection is a read-only projecting wrapper around another RowData: it maps a projected Iceberg schema onto the wrapped row. RowKind mutation is not meaningful for a projection, so setRowKind unconditionally throws UnsupportedOperationException. Reading the kind (getRowKind) delegates to the wrapped row, but writing it is rejected.","triggerScenarios":"Calling setRowKind(...) on a RowDataProjection instance obtained from RowDataProjection.create(...).wrap(row), typically when a Flink operator (e.g. changelog-producing sink or process function) tries to mutate the row kind of a projected row.","commonSituations":"Piping projected rows into a Flink upsert/changelog sink that calls setRowKind; writing generic RowData-manipulating utility code that assumes all RowData implementations are mutable; wrapping rows then trying to tag them with DELETE/UPDATE_BEFORE kinds.","solutions":["Mutate the RowKind on the underlying source RowData before wrapping it with RowDataProjection.","Copy the projected values into a mutable row (e.g. GenericRowData) first, then call setRowKind on that copy.","Construct the projection from a wrapped row that already carries the correct RowKind; getRowKind() passes it through.","If you own the code, replace RowDataProjection with a wrapper that delegates setRowKind to the inner row instead of throwing."],"exampleFix":"// before\nRowData projected = RowDataProjection.create(schema, projectedSchema).wrap(row);\nprojected.setRowKind(RowKind.DELETE); // throws\n\n// after\nGenericRowData mutable = new GenericRowData(projected.getArity());\nfor (int i = 0; i < projected.getArity(); i++) {\n  mutable.setField(i, /* copy field i */ null);\n}\nmutable.setRowKind(RowKind.DELETE);","handlingStrategy":"fallback","validationCode":"if (row instanceof RowDataProjection) {\n  throw new IllegalStateException(\"Mutate the source RowData, not the projection\");\n}","typeGuard":"boolean isMutableRow(RowData row) {\n  return !(row instanceof RowDataProjection);\n}","tryCatchPattern":"try {\n  projected.setRowKind(RowKind.DELETE);\n} catch (UnsupportedOperationException e) {\n  // projected wrapper is read-only: copy to GenericRowData and set kind there\n  GenericRowData copy = copyIntoGenericRow(projected);\n  copy.setRowKind(RowKind.DELETE);\n}","preventionTips":["Treat RowDataProjection as immutable: set RowKind on the wrapped row before projection.","Never pass projections into Flink operators that mutate RowKind (upsert sinks)."],"tags":["flink","rowdata","read-only-wrapper","rowkind"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}