{"record":{"id":"244da37b29feb88f","repo":"apache/iceberg","slug":"cannot-modify-manifestentrywrapper-wrapper-via-set-244da3","errorCode":null,"errorMessage":"Cannot modify ManifestEntryWrapper wrapper via set","messagePattern":"Cannot modify ManifestEntryWrapper wrapper via set","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/V2Metadata.java","lineNumber":306,"sourceCode":"    ManifestEntryWrapper(Long commitSnapshotId) {\n      this.size = entrySchema(Types.StructType.of()).columns().size();\n      this.commitSnapshotId = commitSnapshotId;\n      this.fileWrapper = new DataFileWrapper<>();\n    }\n\n    public ManifestEntryWrapper<F> wrap(ManifestEntry<F> entry) {\n      this.wrapped = entry;\n      return this;\n    }\n\n    @Override\n    public int size() {\n      return size;\n    }\n\n    @Override\n    public <T> void set(int pos, T value) {\n      throw new UnsupportedOperationException(\"Cannot modify ManifestEntryWrapper wrapper via set\");\n    }\n\n    @Override\n    public <T> T get(int pos, Class<T> javaClass) {\n      return javaClass.cast(get(pos));\n    }\n\n    private Object get(int pos) {\n      switch (pos) {\n        case 0:\n          return wrapped.status().id();\n        case 1:\n          return wrapped.snapshotId();\n        case 2:\n          if (wrapped.dataSequenceNumber() == null) {\n            // if the entry's data sequence number is null,\n            // then it will inherit the sequence number of the current commit.\n            // to validate that this is correct, check that the snapshot id is either null (will","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/V2Metadata.java#L288-L324","documentation":"V2Metadata.ManifestEntryWrapper is a read-only StructLike view over a V2 ManifestEntry. Entries (status, sequence numbers, data file) are immutable metadata; set(pos, value) intentionally throws UnsupportedOperationException to prevent in-place mutation that would corrupt snapshot metadata.","triggerScenarios":"Calling set(pos, value) on V2Metadata.ManifestEntryWrapper.wrap(entry), e.g. from code updating entry status or sequence numbers directly during rewrite/expire operations.","commonSituations":"Custom rewrite/compaction jobs mutating entry fields in place; frameworks treating StructLike views as mutable records.","solutions":["Build a new ManifestEntry with the desired status/sequences/file instead of mutating the wrapper","Copy wrapped fields into a fresh Record and modify the copy","Use ManifestWriter APIs to write updated entries rather than editing existing structs"],"exampleFix":"// before\nentryWrapper.set(3, fileSequenceNumber);\n// after\nManifestEntry updated = new ManifestEntry(\n    Status.EXISTING, snapshotId, dataSequenceNumber, fileSequenceNumber, file);","handlingStrategy":"validation","validationCode":"if (entry instanceof V2Metadata.ManifestEntryWrapper) { throw new IllegalStateException(\"V2 ManifestEntryWrapper is read-only; build a new ManifestEntry\"); }","typeGuard":"boolean isReadOnlyV2Entry(Object s) { return s instanceof V2Metadata.ManifestEntryWrapper; }","tryCatchPattern":"try { entryWrapper.set(pos, value); } catch (UnsupportedOperationException e) { throw new IllegalStateException(\"construct a new ManifestEntry instead\", e); }","preventionTips":["Rebuild entries with the ManifestEntry constructor for rewrites","Never mutate sequence numbers on existing entries","Write changes through ManifestWriter APIs"],"tags":["java","unsupported-operation","immutability"],"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"}