{"record":{"id":"c996e5e042e081a2","repo":"apache/iceberg","slug":"cannot-remove-property-that-is-not-set-property-c996e5","errorCode":null,"errorMessage":"Cannot remove property that is not set: '$property'","messagePattern":"Cannot remove property that is not set: '\\$property'","errorType":"exception","errorClass":"IcebergAnalysisException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/AlterV2ViewUnsetPropertiesExec.scala","lineNumber":40,"sourceCode":"import org.apache.spark.sql.catalyst.analysis.IcebergAnalysisException\nimport org.apache.spark.sql.catalyst.expressions.Attribute\nimport org.apache.spark.sql.connector.catalog.Identifier\nimport org.apache.spark.sql.connector.catalog.ViewCatalog\nimport org.apache.spark.sql.connector.catalog.ViewChange\n\ncase class AlterV2ViewUnsetPropertiesExec(\n    catalog: ViewCatalog,\n    ident: Identifier,\n    propertyKeys: Seq[String],\n    ifExists: Boolean)\n    extends LeafV2CommandExec {\n\n  override lazy val output: Seq[Attribute] = Nil\n\n  override protected def run(): Seq[InternalRow] = {\n    if (!ifExists) {\n      propertyKeys.filterNot(catalog.loadView(ident).properties.containsKey).foreach { property =>\n        throw new IcebergAnalysisException(s\"Cannot remove property that is not set: '$property'\")\n      }\n    }\n\n    val changes = propertyKeys.map(ViewChange.removeProperty)\n    catalog.alterView(ident, changes: _*)\n\n    Nil\n  }\n\n  override def simpleString(maxFields: Int): String = {\n    s\"AlterV2ViewUnsetProperties: ${ident}\"\n  }\n}\n","sourceCodeStart":22,"sourceCodeEnd":54,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/AlterV2ViewUnsetPropertiesExec.scala#L22-L54","documentation":"AlterV2ViewUnsetPropertiesExec implements ALTER VIEW ... UNSET TBLPROPERTIES for Iceberg views. Unless IF EXISTS is specified, each property key must currently be set on the view; unsetting an absent property throws IcebergAnalysisException naming the offending property.","triggerScenarios":"Running `ALTER VIEW v UNSET TBLPROPERTIES ('k')` where 'k' is not in the view's properties and the statement lacks IF EXISTS; also any of several listed keys missing causes the first missing key to fail.","commonSituations":"Removing a property that was never set or was already removed (idempotent-cleanup scripts), typos in property names, or case-sensitivity mismatches in keys.","solutions":["Add IF EXISTS: ALTER VIEW v UNSET TBLPROPERTIES IF EXISTS ('k')","Verify the property is set with SHOW TBLPROPERTIES v before unsetting","Correct the property key spelling/case"],"exampleFix":"// before\nALTER VIEW v UNSET TBLPROPERTIES ('comment');\n// after\nALTER VIEW v UNSET TBLPROPERTIES IF EXISTS ('comment');","handlingStrategy":"validation","validationCode":"val props = spark.sql(s\"SHOW TBLPROPERTIES $viewName\").collect().map(_.getString(0)).toSet\nval missing = keys.filterNot(props.contains)\nrequire(missing.isEmpty || ifExists, s\"Properties not set: ${missing.mkString(\",\")}\")","typeGuard":null,"tryCatchPattern":"try { spark.sql(unsetStmt) } catch { case e: IcebergAnalysisException if e.getMessage.contains(\"Cannot remove property that is not set\") => log.warn(s\"Skipping unset: ${e.getMessage}\") }","preventionTips":["Use IF EXISTS for idempotent cleanup scripts","Check SHOW TBLPROPERTIES before UNSET","Keep a canonical map of property key names/case"],"tags":["spark","iceberg","views","properties"],"backgroundTag":"missing-required-argument","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"}