{"record":{"id":"678f6a93419cb9c2","repo":"apache/iceberg","slug":"cannot-modify-manifestentrywrapper-wrapper-via-set","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/V1Metadata.java","lineNumber":260,"sourceCode":"\n    ManifestEntryWrapper() {\n      this.size = entrySchema(Types.StructType.of()).columns().size();\n      this.fileWrapper = new DataFileWrapper();\n    }\n\n    public ManifestEntryWrapper wrap(ManifestEntry<DataFile> 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          DataFile file = wrapped.file();\n          if (file != null) {\n            return fileWrapper.wrap(file);\n          }","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/V1Metadata.java#L242-L278","documentation":"ManifestEntryWrapper in V1Metadata is a read-only StructLike view over a ManifestEntry. Manifest entries are immutable metadata records; set(pos, value) deliberately throws UnsupportedOperationException to prevent in-place corruption of entry data (status, snapshot ids, data file).","triggerScenarios":"Calling set(pos, value) on a ManifestEntryWrapper produced by V1Metadata.ManifestEntryWrapper.wrap(entry), e.g. from generic writers or code that mutates entry status/fields in place.","commonSituations":"Custom manifest writers or rewrite jobs that try to update entry status or data file in place; frameworks that treat all StructLike instances as mutable records.","solutions":["Do not mutate the wrapper; build a new ManifestEntry (e.g. via entry builder) with the desired status/file","Copy the wrapped fields into a fresh Record and modify the copy","For rewriting entries, use ManifestWriter/ManifestWriter factories rather than mutating existing structs"],"exampleFix":"// before\nentryWrapper.set(0, Status.DELETED);\n// after\nManifestEntry updated = new ManifestEntry(Status.DELETED, entry.snapshotId(), entry.dataSequenceNumber(), entry.fileSequenceNumber(), entry.file());","handlingStrategy":"validation","validationCode":"if (entry instanceof V1Metadata.ManifestEntryWrapper) { throw new IllegalStateException(\"ManifestEntryWrapper is read-only; build a new ManifestEntry\"); }","typeGuard":"boolean isReadOnlyEntry(Object s) { return s instanceof V1Metadata.ManifestEntryWrapper || s instanceof V2Metadata.ManifestEntryWrapper; }","tryCatchPattern":"try { entryWrapper.set(pos, value); } catch (UnsupportedOperationException e) { throw new IllegalStateException(\"use ManifestEntry builder instead of mutating entry\", e); }","preventionTips":["Create new ManifestEntry objects for status/file changes","Use ManifestWriter rather than mutating existing entries","Assume all StructLike views in core metadata are immutable"],"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"}