{"record":{"id":"bcd54ccbaffcb31e","repo":"apache/iceberg","slug":"cannot-modify-manifestfilewrapper-wrapper-via-set","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/V1Metadata.java","lineNumber":68,"sourceCode":"   * <p>This is used to maintain compatibility with v1 by writing manifest list files with the old\n   * schema, instead of writing a sequence number into metadata files in v1 tables.\n   */\n  static class ManifestFileWrapper implements ManifestFile, StructLike {\n    private ManifestFile wrapped = null;\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 path();\n        case 1:\n          return length();\n        case 2:\n          return partitionSpecId();\n        case 3:\n          return snapshotId();\n        case 4:","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/V1Metadata.java#L50-L86","documentation":"ManifestFileWrapper is a read-only StructLike view over a ManifestFile in V1Metadata. Its set(pos, value) is intentionally unimplemented because manifests are immutable metadata; mutating a wrapped manifest file would corrupt table metadata. The library throws UnsupportedOperationException to enforce read-only access.","triggerScenarios":"Calling set(pos, value) on a ManifestFileWrapper obtained via V1Metadata.ManifestFileWrapper.wrap(manifestFile), e.g. when writing manifests via a GenericDataWriter or when code treats the StructLike as mutable.","commonSituations":"Custom catalog or writer code that reuses a mutable StructLike buffer across records and calls set() on manifest-file structs; reflection-based frameworks (Avro/GenericData) attempting in-place mutation of manifest list records.","solutions":["Do not call set on the wrapper; construct a new ManifestFile/Record instead of mutating the wrapped one","If you need a mutable record, copy fields via get(pos) into your own Record and modify that","Check that custom writers use ManifestFile itself, not the read-only wrapper, when serializing"],"exampleFix":"// before\nstructLike.set(0, newPath);\n// after\nRecord copy = GenericRecord.create(MANIFEST_LIST_SCHEMA.asStruct()).copy(structLike);\ncopy.set(0, newPath);","handlingStrategy":"validation","validationCode":"if (wrapper instanceof V1Metadata.ManifestFileWrapper) { throw new IllegalStateException(\"read-only wrapper; copy fields instead of set()\"); }","typeGuard":"boolean isReadOnlyWrapper(Object s) { return s instanceof V1Metadata.ManifestFileWrapper || s instanceof V1Metadata.ManifestEntryWrapper || s instanceof V1Metadata.DataFileWrapper; }","tryCatchPattern":"try { structLike.set(pos, value); } catch (UnsupportedOperationException e) { Record copy = GenericRecord.create(schema.asStruct()).copy(structLike); copy.set(pos, value); }","preventionTips":["Treat all Iceberg metadata StructLike wrappers as read-only","Copy into a GenericRecord before modifying metadata structs","Never reuse manifest wrappers as mutable write buffers"],"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"}