{"record":{"id":"8b460de575b55625","repo":"apache/iceberg","slug":"struct-copy-cannot-be-modified","errorCode":null,"errorMessage":"Struct copy cannot be modified","messagePattern":"Struct copy cannot be modified","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/util/StructLikeUtil.java","lineNumber":64,"sourceCode":"        } else {\n          values[i] = value;\n        }\n      }\n    }\n\n    @Override\n    public int size() {\n      return values.length;\n    }\n\n    @Override\n    public <T> T get(int pos, Class<T> javaClass) {\n      return javaClass.cast(values[pos]);\n    }\n\n    @Override\n    public <T> void set(int pos, T value) {\n      throw new UnsupportedOperationException(\"Struct copy cannot be modified\");\n    }\n  }\n}\n","sourceCodeStart":46,"sourceCodeEnd":68,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/util/StructLikeUtil.java#L46-L68","documentation":"StructLikeUtil.copy creates an immutable snapshot copy of a StructLike row; the returned copy's set method deliberately throws UnsupportedOperationException because the copy exists only to hold stable values (e.g. as a map key). Attempting to write into the copy fails.","triggerScenarios":"Storing a StructLikeUtil.copy(...) result and later trying to update a field via set(pos, value); reusing a copied row as a mutable record buffer.","commonSituations":"Using copied rows as dedup/map keys then attempting to overwrite them; code that assumed copy() returned a mutable clone like InternalRecord copy semantics.","solutions":["Create a mutable instance (e.g. GenericRecord or the original StructLike) instead of writing to the copy","Copy again from a mutable template: build a new mutable row, set fields, then copy if needed for keying","Read-only accessors (get) are safe; refactor mutation code to operate on the source record before copying"],"exampleFix":"// before\nStructLike snapshot = StructLikeUtil.copy(type, record);\nsnapshot.set(0, newValue); // throws\n// after\nStructLike mutable = new RecordTuple(GenericRecord.create(type));\nmutable.set(0, newValue);\nStructLike key = StructLikeUtil.copy(type, mutable);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"boolean isImmutableCopy(StructLike s) {\n  try { s.set(0, s.get(0, Object.class)); return false; }\n  catch (UnsupportedOperationException e) { return true; }\n  catch (Exception e) { return false; }\n}","tryCatchPattern":null,"preventionTips":["Treat StructLikeUtil.copy results as strictly read-only","Use copies only as map keys or stable snapshots","Perform mutations on the source record before copying","Check target StructLike mutability before writing"],"tags":["immutability","structlike"],"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"}