{"record":{"id":"1d5d6a45ef77893d","repo":"apache/iceberg","slug":"cannot-remove-or-replace-rows-in-a-s-table","errorCode":null,"errorMessage":"Cannot remove or replace rows in a %s table","messagePattern":"Cannot remove or replace rows in a (.+?) table","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/BaseReadOnlyTable.java","lineNumber":82,"sourceCode":"  @Override\n  public RewriteFiles newRewrite() {\n    throw new UnsupportedOperationException(\"Cannot rewrite in a \" + descriptor + \" table\");\n  }\n\n  @Override\n  public RewriteManifests rewriteManifests() {\n    throw new UnsupportedOperationException(\n        \"Cannot rewrite manifests in a \" + descriptor + \" table\");\n  }\n\n  @Override\n  public OverwriteFiles newOverwrite() {\n    throw new UnsupportedOperationException(\"Cannot overwrite in a \" + descriptor + \" table\");\n  }\n\n  @Override\n  public RowDelta newRowDelta() {\n    throw new UnsupportedOperationException(\n        \"Cannot remove or replace rows in a \" + descriptor + \" table\");\n  }\n\n  @Override\n  public ReplacePartitions newReplacePartitions() {\n    throw new UnsupportedOperationException(\n        \"Cannot replace partitions in a \" + descriptor + \" table\");\n  }\n\n  @Override\n  public DeleteFiles newDelete() {\n    throw new UnsupportedOperationException(\"Cannot delete from a \" + descriptor + \" table\");\n  }\n\n  @Override\n  public UpdateStatistics updateStatistics() {\n    throw new UnsupportedOperationException(\n        \"Cannot update statistics of a \" + descriptor + \" table\");","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/BaseReadOnlyTable.java#L64-L100","documentation":"Iceberg throws this UnsupportedOperationException when newRowDelta() is called on a read-only table. RowDelta commits data and delete files (row-level changes), which BaseReadOnlyTable subclasses never allow. The descriptor names the read-only table kind.","triggerScenarios":"Calling table.newRowDelta().addRows(...).addDeletes(...).commit() on a metadata table or any BaseReadOnlyTable subclass instance.","commonSituations":"Row-level delete writers (e.g. CDC or merge-on-read writers) that were given a metadata-table handle instead of the data table.","solutions":["Build the RowDelta on the writable data table loaded via catalog.loadTable(identifier).","Validate the Table reference is a real data table before instantiating writers.","Use RowDelta only for v2 tables; ensure the target table has format version 2."],"exampleFix":"// before\ntable.snapshots().newRowDelta().addRows(writer).commit();\n\n// after\nTable dataTable = catalog.loadTable(TableIdentifier.of(\"db\", \"tbl\"));\ndataTable.newRowDelta().addRows(writer).commit();","handlingStrategy":"try-catch","validationCode":"if (isMetadataTableName(table.name())) { throw new IllegalArgumentException(\"Cannot apply row deltas to metadata table \" + table.name()); }","typeGuard":"boolean canWriteRowDelta = !(table instanceof BaseReadOnlyTable); // ensure handle came from Catalog.loadTable","tryCatchPattern":"try {\n  table.newRowDelta().addRows(writer).commit();\n} catch (UnsupportedOperationException e) {\n  log.error(\"RowDelta is not supported on read-only table {}\", table.name(), e);\n}","preventionTips":["Bind delete/row writers to catalog-loaded data tables only.","Confirm format version 2 before using RowDelta on the data table.","Keep metadata-table handles out of writer construction code paths."],"tags":["unsupported-operation","row-delta","read-only-table"],"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"}