{"record":{"id":"83ad479dbdb067e4","repo":"apache/iceberg","slug":"unsupported-operation-mode-mode-83ad47","errorCode":null,"errorMessage":"Unsupported operation mode: + mode","messagePattern":"Unsupported operation mode: \\+ mode","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkRowLevelOperationBuilder.java","lineNumber":71,"sourceCode":"  SparkRowLevelOperationBuilder(\n      SparkSession spark, Table table, String branch, RowLevelOperationInfo info) {\n    this.spark = spark;\n    this.table = table;\n    this.branch = branch;\n    this.info = info;\n    this.mode = mode(table.properties(), info.command());\n    this.isolationLevel = isolationLevel(table.properties(), info.command());\n  }\n\n  @Override\n  public RowLevelOperation build() {\n    switch (mode) {\n      case COPY_ON_WRITE:\n        return new SparkCopyOnWriteOperation(spark, table, branch, info, isolationLevel);\n      case MERGE_ON_READ:\n        return new SparkPositionDeltaOperation(spark, table, branch, info, isolationLevel);\n      default:\n        throw new IllegalArgumentException(\"Unsupported operation mode: \" + mode);\n    }\n  }\n\n  private RowLevelOperationMode mode(Map<String, String> properties, Command command) {\n    String modeName;\n\n    switch (command) {\n      case DELETE:\n        modeName = properties.getOrDefault(DELETE_MODE, DELETE_MODE_DEFAULT);\n        break;\n      case UPDATE:\n        modeName = properties.getOrDefault(UPDATE_MODE, UPDATE_MODE_DEFAULT);\n        break;\n      case MERGE:\n        modeName = properties.getOrDefault(MERGE_MODE, MERGE_MODE_DEFAULT);\n        break;\n      default:\n        throw new IllegalArgumentException(\"Unsupported command: \" + command);","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkRowLevelOperationBuilder.java#L53-L89","documentation":"SparkRowLevelOperationBuilder.build() maps the resolved RowLevelOperationMode to either SparkCopyOnWriteOperation or SparkPositionDeltaOperation. Any mode other than COPY_ON_WRITE or MERGE_ON_READ hits the default branch and throws this IllegalArgumentException. There is no third row-level write mode in the Iceberg Spark integration.","triggerScenarios":"Table properties such as write.update.mode / write.delete.mode / write.merge.mode are set to an unrecognized string that RowLevelOperationMode.fromName() resolves to a non-standard mode value, then passed to build().","commonSituations":"Typos in mode properties (e.g. 'copy-on-write ', 'MOR', 'cow'); hand-edited table properties; property values written by other engines or older versions with different names.","solutions":["Set mode properties to exactly 'copy-on-write' or 'merge-on-read' (case handled by fromName, but no other values are valid).","Inspect table properties with DESCRIBE TABLE / metadata and remove or correct the bad *.*.mode keys.","Remove the invalid property to fall back to the default mode for the command.","Check RowLevelOperationMode.fromName() for accepted names before setting properties."],"exampleFix":"// before\nALTER TABLE t SET TBLPROPERTIES ('write.merge.mode'='mor');\n// after\nALTER TABLE t SET TBLPROPERTIES ('write.merge.mode'='merge-on-read');","handlingStrategy":"validation","validationCode":"Set<String> valid = Set.of(\"copy-on-write\", \"merge-on-read\");\nString mode = props.getOrDefault(\"write.merge.mode\", \"copy-on-write\");\nif (!valid.contains(mode.toLowerCase(Locale.ROOT))) {\n  throw new IllegalArgumentException(\"Bad write mode: \" + mode);\n}","typeGuard":null,"tryCatchPattern":"try { RowLevelOperation op = builder.build(); } catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Unsupported operation mode\")) { fixTableModeProperty(e); }\n  else throw e;\n}","preventionTips":["Set write.*.mode properties only to 'copy-on-write' or 'merge-on-read'","Read properties back via DESCRIBE TABLE after edits","Avoid hand-editing table metadata JSON"],"tags":["spark","configuration","row-level-operations"],"backgroundTag":"invalid-enum-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}