{"record":{"id":"a6d0a6069aed9209","repo":"apache/druid","slug":"catalogexception-validationerror-e-wraps-iae-dru-a6d0a6","errorCode":null,"errorMessage":"CatalogException.validationError(e) (wraps IAE/DruidException validation message)","messagePattern":"CatalogException\\.validationError\\(e\\) \\(wraps IAE/DruidException validation message\\)","errorType":"validation","errorClass":"CatalogException","httpStatus":400,"severity":"error","filePath":"extensions-core/druid-catalog/src/main/java/org/apache/druid/catalog/http/TableEditor.java","lineNumber":317,"sourceCode":"    return catalog.tables().updateColumns(\n        id,\n        table -> applyUpdateColumns(table, updates)\n    );\n  }\n\n  private TableSpec applyUpdateColumns(\n      final TableMetadata table,\n      final List<ColumnSpec> updates\n  ) throws CatalogException\n  {\n    final TableSpec existingSpec = table.spec();\n    final TableDefn defn = resolveDefn(existingSpec.type());\n    final List<ColumnSpec> revised = defn.mergeColumns(existingSpec.columns(), updates);\n    try {\n      defn.validateColumns(revised);\n    }\n    catch (IAE | DruidException e) {\n      throw CatalogException.validationError(e);\n    }\n    return existingSpec.withColumns(revised);\n  }\n\n  private long moveColumn(MoveColumn moveColumn) throws CatalogException\n  {\n    if (Strings.isNullOrEmpty(moveColumn.column)) {\n      throw CatalogException.badRequest(\"A column name is required\");\n    }\n    if (moveColumn.where == null) {\n      throw CatalogException.badRequest(\"A target location is required\");\n    }\n    if ((moveColumn.where == Position.BEFORE || moveColumn.where == Position.AFTER) && Strings.isNullOrEmpty(moveColumn.anchor)) {\n      throw CatalogException.badRequest(\"A anchor column is required for BEFORE or AFTER\");\n    }\n    return catalog.tables().updateColumns(\n        id,\n        table -> applyMoveColumn(table, moveColumn)","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-catalog/src/main/java/org/apache/druid/catalog/http/TableEditor.java#L299-L335","documentation":"TableEditor.applyUpdateColumns merges column updates into the existing spec and validates the revised column list with defn.validateColumns(revised); failures (IAE/DruidException) are wrapped in CatalogException.validationError(e). This guards against updates that would leave the table's columns invalid (duplicates, type changes violating rules, etc.).","triggerScenarios":"Submitting an updateColumns operation to the table editor where the merged column list fails definition-level validation, e.g. renaming to an existing column name, changing a column type in a disallowed way, or dropping a required column.","commonSituations":"Concurrent edits based on stale column lists; batch updates combining several column changes where one is invalid; tooling that generates column diffs with conflicting names.","solutions":["Fix the offending column update per the wrapped validation message.","Fetch the latest table spec first so merges are applied on a current column list.","Split large column updates into smaller changes to isolate the invalid one.","Re-run validation locally by constructing the TableDefn and calling validateColumns on the merged list."],"exampleFix":"// before: update adds a column named 'ts' when 'ts' already exists\n// after: rename new column to 'ts2' or drop/replace the existing one","handlingStrategy":"try-catch","validationCode":"// Re-apply the merge locally and validate before submitting\nList<ColumnSpec> merged = defn.mergeColumns(existingSpec.columns(), updates);\ndefn.validateColumns(merged); // throws before the server does","typeGuard":null,"tryCatchPattern":"try { editor.updateColumns(tableId, updates); }\ncatch (CatalogException e) { if (e.isValidation()) { refreshSpecAndRetryWithFixedUpdates(e); } else { throw e; } }","preventionTips":["Always fetch the current spec before computing column updates.","Avoid name collisions between new and existing columns.","Validate merged column lists with TableDefn.validateColumns in unit tests."],"tags":["catalog","columns","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}