{"record":{"id":"0e14798ee6deba66","repo":"apache/iceberg","slug":"cannot-modify-manifestfilewrapper-wrapper-via-set-0e1479","errorCode":null,"errorMessage":"Cannot modify ManifestFileWrapper wrapper via set","messagePattern":"Cannot modify ManifestFileWrapper wrapper via set","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/V2Metadata.java","lineNumber":79,"sourceCode":"\n    ManifestFileWrapper(long commitSnapshotId, long sequenceNumber) {\n      this.commitSnapshotId = commitSnapshotId;\n      this.sequenceNumber = sequenceNumber;\n    }\n\n    public ManifestFile wrap(ManifestFile file) {\n      this.wrapped = file;\n      return this;\n    }\n\n    @Override\n    public int size() {\n      return MANIFEST_LIST_SCHEMA.columns().size();\n    }\n\n    @Override\n    public <T> void set(int pos, T value) {\n      throw new UnsupportedOperationException(\"Cannot modify ManifestFileWrapper 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.path();\n        case 1:\n          return wrapped.length();\n        case 2:\n          return wrapped.partitionSpecId();\n        case 3:\n          checkContentType(wrapped.content());\n          return wrapped.content().id();","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/V2Metadata.java#L61-L97","documentation":"V2Metadata.ManifestFileWrapper is a read-only StructLike view over a V2 ManifestFile. Manifest files are immutable metadata; set(pos, value) deliberately throws UnsupportedOperationException so wrapped manifest-list records cannot be altered in place.","triggerScenarios":"Calling set(pos, value) on V2Metadata.ManifestFileWrapper.wrap(manifestFile), e.g. from generic writers or mutation-style StructLike code.","commonSituations":"Custom catalog/writer code reusing mutable records across manifest files; frameworks that assume all StructLike views are writable.","solutions":["Construct a new ManifestFile/Record instead of mutating the wrapper","Copy fields out with get(pos) into your own record and modify the copy","Ensure custom writers serialize the ManifestFile itself, not the read-only wrapper"],"exampleFix":"// before\nwrapper.set(12, partitionsField);\n// after\nRecord copy = GenericRecord.create(MANIFEST_LIST_SCHEMA.asStruct()).copy(wrapper);\ncopy.set(12, partitionsField);","handlingStrategy":"validation","validationCode":"if (wrapper instanceof V2Metadata.ManifestFileWrapper) { throw new IllegalStateException(\"read-only wrapper; copy before modifying\"); }","typeGuard":"boolean isReadOnlyManifest(Object s) { return s instanceof V2Metadata.ManifestFileWrapper; }","tryCatchPattern":"try { wrapper.set(pos, value); } catch (UnsupportedOperationException e) { Record copy = GenericRecord.create(MANIFEST_LIST_SCHEMA.asStruct()).copy(wrapper); copy.set(pos, value); }","preventionTips":["Treat V2 metadata wrappers as immutable like V1","Copy to GenericRecord for any field mutation","Serialize the ManifestFile, not the wrapper, in writers"],"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"}