{"record":{"id":"70bca3fd63f46f7c","repo":"apache/iceberg","slug":"not-implemented-set","errorCode":null,"errorMessage":"Not implemented: set","messagePattern":"Not implemented: set","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkStructLike.java","lineNumber":52,"sourceCode":"  public SparkStructLike wrap(Row row) {\n    this.wrapped = row;\n    return this;\n  }\n\n  @Override\n  public int size() {\n    return type.fields().size();\n  }\n\n  @Override\n  public <T> T get(int pos, Class<T> javaClass) {\n    Types.NestedField field = type.fields().get(pos);\n    return javaClass.cast(SparkValueConverter.convert(field.type(), wrapped.get(pos)));\n  }\n\n  @Override\n  public <T> void set(int pos, T value) {\n    throw new UnsupportedOperationException(\"Not implemented: set\");\n  }\n}\n","sourceCodeStart":34,"sourceCodeEnd":55,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkStructLike.java#L34-L55","documentation":"SparkStructLike is a read-only wrapper that adapts an Iceberg StructLike row into Spark internal (Catalyst) values; get() converts values for reading, but mutation is intentionally unimplemented. Calling set(pos, value) always throws UnsupportedOperationException because rows produced for scanning are immutable views, not writable buffers.","triggerScenarios":"Any code path calling SparkStructLike.set(pos, value) — e.g. writing into the wrapped struct during upserts, merges, or generic code assuming a mutable StructLike.","commonSituations":"Custom merge/upsert logic that mutates rows in place; test harnesses reusing a StructLike instance as an accumulator; generic Iceberg code that writes to StructLike passed a Spark-backed wrapper.","solutions":["Do not mutate SparkStructLike; build a new record/Row with the changed value instead.","Use a mutable StructLike implementation (e.g. GenericsHelpers record) as the write target, then wrap it read-only with SparkStructLike for conversion.","If writing Spark rows, use the Spark writer APIs (SparkWrite) rather than mutating scan-produced structs."],"exampleFix":"// before\nsparkStructLike.set(pos, newValue); // throws UnsupportedOperationException\n// after\nGenericData.Record record = new GenericData.Record(sparkStructLike.structType());\nfor (int i = 0; i < record.size(); i++) record.set(i, sparkStructLike.get(i, Object.class));\nrecord.set(pos, newValue);","handlingStrategy":"type-guard","validationCode":"// treat SparkStructLike strictly as read-only in your code; never pass it where a mutable StructLike is required\nif (structLike instanceof SparkStructLike) { /* read-only: do not call set */ }","typeGuard":"boolean isWritable = !(structLike instanceof SparkStructLike);","tryCatchPattern":"try {\n  structLike.set(pos, value);\n} catch (UnsupportedOperationException e) {\n  if (\"Not implemented: set\".equals(e.getMessage())) { /* copy record and mutate the copy */ }\n  else throw e;\n}","preventionTips":["Never mutate rows returned by Iceberg scans; copy into a GenericData.Record first.","Use mutable record implementations when accumulating/updating values.","Keep SparkStructLike strictly on the read/conversion path."],"tags":["unsupported-operation","immutable","structlike","read-only"],"backgroundTag":"method-not-implemented","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}