{"record":{"id":"0c288526751b5548","repo":"apache/iceberg","slug":"cannot-validate-s-against-a-table","errorCode":null,"errorMessage":"Cannot validate %s against a table","messagePattern":"Cannot validate (.+?) against a table","errorType":"exception","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/UpdateRequirement.java","lineNumber":29,"sourceCode":" *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.apache.iceberg;\n\nimport org.apache.iceberg.exceptions.CommitFailedException;\nimport org.apache.iceberg.exceptions.ValidationException;\nimport org.apache.iceberg.relocated.com.google.common.base.Preconditions;\nimport org.apache.iceberg.view.ViewMetadata;\n\n/** Represents a requirement for a {@link MetadataUpdate} */\npublic interface UpdateRequirement {\n  default void validate(TableMetadata base) {\n    throw new ValidationException(\n        \"Cannot validate %s against a table\", this.getClass().getSimpleName());\n  }\n\n  default void validate(ViewMetadata base) {\n    throw new ValidationException(\n        \"Cannot validate %s against a view\", this.getClass().getSimpleName());\n  }\n\n  class AssertTableDoesNotExist implements UpdateRequirement {\n    public AssertTableDoesNotExist() {}\n\n    @Override\n    public void validate(TableMetadata base) {\n      if (base != null) {\n        throw new CommitFailedException(\"Requirement failed: table already exists\");\n      }\n    }\n  }","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/UpdateRequirement.java#L11-L47","documentation":"UpdateRequirement is the interface for commit requirements (assertions on base metadata). Its default validate(TableMetadata) throws ValidationException because each concrete requirement either validates against a table or a view, not both. Calling validate(base) with a TableMetadata on a requirement that only supports views (or calling the interface default directly on an unsupported subtype) hits this throw.","triggerScenarios":"Invoking UpdateRequirement.validate(TableMetadata) on a requirement subclass that only overrides validate(ViewMetadata), or on a stub/default implementation.","commonSituations":"Generic commit-apply code that dispatches all requirements against table metadata without checking whether the requirement is view-scoped.","solutions":["Dispatch view-scoped requirements to validate(ViewMetadata) instead of validate(TableMetadata).","Use the requirement's concrete type (e.g., AssertViewUUID) to decide which metadata type to pass.","Upgrade Iceberg if a requirement subclass is missing its table-side validate override."],"exampleFix":"// before\nrequirement.validate(tableMetadata); // view-only requirement\n\n// after\nif (requirement instanceof UpdateRequirement.ViewRequirement) {\n  requirement.validate(viewMetadata);\n} else {\n  requirement.validate(tableMetadata);\n}","handlingStrategy":"type-guard","validationCode":"boolean isViewScoped = requirement instanceof UpdateRequirement.ViewRequirement;","typeGuard":"if (requirement instanceof UpdateRequirement.ViewRequirement vr) { vr.validate(viewMetadata); } else { requirement.validate(tableMetadata); }","tryCatchPattern":"try { requirement.validate(base); } catch (ValidationException e) { /* wrong metadata type for this requirement; re-dispatch */ }","preventionTips":["Dispatch requirements by their target metadata type, not a single validate call.","Group view requirements separately from table requirements during commit apply.","Ensure every concrete requirement overrides the applicable validate()."],"tags":["validation-exception","commit-requirement","type-mismatch"],"backgroundTag":"type-mismatch","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"}