{"record":{"id":"e4df05ee25ec4e28","repo":"apache/iceberg","slug":"cannot-remove-property-that-is-not-set-property","errorCode":null,"errorMessage":"Cannot remove property that is not set: '$property'","messagePattern":"Cannot remove property that is not set: '\\$property'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/AlterV2ViewUnsetPropertiesExec.scala","lineNumber":40,"sourceCode":"import org.apache.spark.sql.catalyst.InternalRow\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 AnalysisException(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/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/AlterV2ViewUnsetPropertiesExec.scala#L22-L54","documentation":"ALTER VIEW ... UNSET PROPERTIES without IF EXISTS fails if any listed property key is not currently set on the view. The exec scans the view's properties and throws an AnalysisException naming the first missing key; with IF EXISTS the missing keys are silently skipped.","triggerScenarios":"Running ALTER VIEW v UNSET TBLPROPERTIES ('k') where 'k' is absent from the view's properties and the statement lacks IF EXISTS.","commonSituations":"Idempotent cleanup scripts re-unsetting already-removed properties; typo'd property keys; concurrent removal by another job.","solutions":["Add IF EXISTS: ALTER VIEW v UNSET TBLPROPERTIES IF EXISTS ('k')","Check current properties first (e.g. DESCRIBE VIEW EXTENDED or catalog API) and only unset keys that are present","Correct the property key spelling"],"exampleFix":"// before\nALTER VIEW catalog.db.v UNSET TBLPROPERTIES ('comment');\n// after\nALTER VIEW catalog.db.v UNSET TBLPROPERTIES IF EXISTS ('comment');","handlingStrategy":"try-catch","validationCode":"val view = catalog.loadView(ident)\nval missing = propertyKeys.filterNot(key => view.properties.containsKey(key))\nrequire(missing.isEmpty || ifExists, s\"Properties not set: $missing\")","typeGuard":null,"tryCatchPattern":"try { spark.sql(unsetDdl) } catch { case e: AnalysisException if e.getMessage.contains(\"Cannot remove property that is not set\") => log.warn(\"property already unset; use IF EXISTS\") }","preventionTips":["Always append IF EXISTS for idempotent property cleanup scripts","Inspect view properties before unsetting (DESCRIBE VIEW EXTENDED)","Guard against concurrent jobs unsetting the same properties"],"tags":["spark","views","properties"],"backgroundTag":"invalid-state-transition","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"}