{"record":{"id":"0e4c7d4aafda571b","repo":"apache/iceberg","slug":"invalid-value-for-sparksqlproperties-view-schema","errorCode":null,"errorMessage":"Invalid value for ${SparkSQLProperties.VIEW_SCHEMA_BINDING_MODE}: $mode, expected ${SparkSQLProperties.VIEW_SCHEMA_MODE_BINDING} or ${SparkSQLProperties.VIEW_SCHEMA_MODE_COMPENSATION}","messagePattern":"Invalid value for (.+?): \\$mode, expected (.+?) or (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveViews.scala","lineNumber":145,"sourceCode":"\n    SubqueryAlias(nameParts, Project(aliases, rewritten))\n  }\n\n  // Read on every resolution rather than cached, so that SET takes effect within a session.\n  private def viewSchemaMode: String =\n    parseSchemaBindingMode(\n      conf.getConfString(\n        SparkSQLProperties.VIEW_SCHEMA_BINDING_MODE,\n        SparkSQLProperties.VIEW_SCHEMA_MODE_BINDING))\n\n  private def parseSchemaBindingMode(mode: String): String = {\n    val normalized = mode.trim\n    if (normalized.equalsIgnoreCase(SparkSQLProperties.VIEW_SCHEMA_MODE_BINDING)) {\n      SparkSQLProperties.VIEW_SCHEMA_MODE_BINDING\n    } else if (normalized.equalsIgnoreCase(SparkSQLProperties.VIEW_SCHEMA_MODE_COMPENSATION)) {\n      SparkSQLProperties.VIEW_SCHEMA_MODE_COMPENSATION\n    } else {\n      throw new IllegalArgumentException(\n        s\"Invalid value for ${SparkSQLProperties.VIEW_SCHEMA_BINDING_MODE}: $mode, expected \" +\n          s\"${SparkSQLProperties.VIEW_SCHEMA_MODE_BINDING} or \" +\n          s\"${SparkSQLProperties.VIEW_SCHEMA_MODE_COMPENSATION}\")\n    }\n  }\n\n  private def parseViewText(name: String, viewText: String): LogicalPlan = {\n    val origin = Origin(objectType = Some(\"VIEW\"), objectName = Some(name))\n\n    try {\n      CurrentOrigin.withOrigin(origin) {\n        spark.sessionState.sqlParser.parseQuery(viewText)\n      }\n    } catch {\n      case _: ParseException =>\n        throw QueryCompilationErrors.invalidViewText(viewText, name)\n    }\n  }","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveViews.scala#L127-L163","documentation":"Thrown when the spark.sql iceberg view schema-binding-mode property is set to a value other than 'binding' or 'compensation' (case-insensitive; the value is trimmed). The library validates this config because view schema evolution behavior must be one of the two supported modes.","triggerScenarios":"Setting SparkSQLProperties.VIEW_SCHEMA_BINDING_MODE (spark.sql-view-schema-binding-mode style config) via SQLConf, SparkConf, or session config to any unrecognized string such as 'bind', 'compat', or 'none'.","commonSituations":"Typos in spark config files or SQL SET commands; copy-pasted config from a different engine; documentation drift across Iceberg/Spark versions where mode names changed.","solutions":["Set the property to exactly 'binding' or 'compensation' (case-insensitive): SET spark.sql-view-schema-binding-mode=compensation;","Unset the property to use the library default instead of supplying a custom value","Check the SparkSQLProperties constants in your Iceberg version for the accepted values"],"exampleFix":"// before\nSET spark.sql-view-schema-binding-mode = compat;\n// after\nSET spark.sql-view-schema-binding-mode = compensation;","handlingStrategy":"validation","validationCode":"val mode = spark.conf.getOption(\"spark.sql-view-schema-binding-mode\")\nval allowed = Set(\"binding\", \"compensation\")\nmode.foreach(m => require(allowed.contains(m.trim.toLowerCase), s\"Invalid view schema binding mode: $m\"))","typeGuard":"def isValidViewSchemaMode(m: String): Boolean =\n  Set(\"binding\", \"compensation\").contains(m.trim.toLowerCase)","tryCatchPattern":null,"preventionTips":["Keep mode values lowercase literals 'binding' or 'compensation' in config files","Reference SparkSQLProperties constants instead of hardcoding strings","Add a config smoke test at session startup"],"tags":["spark","config","iceberg-views"],"backgroundTag":"invalid-config-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"}