{"record":{"id":"0a827a17232e0a5d","repo":"apache/seatunnel","slug":"fileschemaevolution-drop-event-references-unknow","errorCode":null,"errorMessage":"[FileSchemaEvolution] DROP event references unknown column '{}' — ignored","messagePattern":"\\[FileSchemaEvolution\\] DROP event references unknown column '(.+?)' — ignored","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sink/writer/AbstractWriteStrategy.java","lineNumber":358,"sourceCode":"            boolean alreadyPresent =\n                    sinkColumnNames.stream().anyMatch(c -> c.equalsIgnoreCase(newCol));\n            if (!alreadyPresent) {\n                if (e.isFirst()) {\n                    sinkColumnNames.add(0, newCol);\n                } else if (e.getAfterColumn() != null) {\n                    int pos = indexOfIgnoreCase(sinkColumnNames, e.getAfterColumn());\n                    sinkColumnNames.add(pos >= 0 ? pos + 1 : sinkColumnNames.size(), newCol);\n                } else {\n                    sinkColumnNames.add(newCol);\n                }\n            }\n        } else if (event instanceof AlterTableDropColumnEvent) {\n            // Case-insensitive removal: CDC sources may send column names in any case\n            String toDrop = ((AlterTableDropColumnEvent) event).getColumn();\n            boolean removed = sinkColumnNames.removeIf(c -> c.equalsIgnoreCase(toDrop));\n            if (!removed) {\n                log.warn(\n                        \"[FileSchemaEvolution] DROP event references unknown column '{}' — ignored\",\n                        toDrop);\n            }\n        } else if (event instanceof AlterTableChangeColumnEvent) {\n            // RENAME (and optional MOVE): remove old name, insert new name at target position.\n            // AlterTableChangeColumnEvent covers MySQL's CHANGE COLUMN which can rename and\n            // reorder in one statement. Both the rename and the position change are applied.\n            AlterTableChangeColumnEvent e = (AlterTableChangeColumnEvent) event;\n            int idx = indexOfIgnoreCase(sinkColumnNames, e.getOldColumn());\n            if (idx >= 0) {\n                sinkColumnNames.remove(idx);\n                String newName = e.getColumn().getName();\n                if (e.isFirst()) {\n                    sinkColumnNames.add(0, newName);\n                } else if (e.getAfterColumn() != null) {\n                    int afterIdx = indexOfIgnoreCase(sinkColumnNames, e.getAfterColumn());\n                    sinkColumnNames.add(\n                            afterIdx >= 0 ? afterIdx + 1 : sinkColumnNames.size(), newName);\n                } else {","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sink/writer/AbstractWriteStrategy.java#L340-L376","documentation":"A WARN from AbstractWriteStrategy.updateSinkColumnNames during schema evolution: an AlterTableDropColumnEvent named a column that does not exist in the current sink schema (comparison is case-insensitive), so the DROP is ignored and the file schema is left unchanged. This prevents index-out-of-bounds or silent corruption from stale/mismatched CDC events.","triggerScenarios":"applySchemaChange -> updateSinkColumnNames receives a DROP event whose column was already dropped upstream, was never part of the sink projection (source selects a subset), or differs due to case handled correctly but still absent from sinkColumnNames.","commonSituations":"Replaying CDC from an earlier binlog position re-sending old DROP events; multiple upstream pipelines both dropping the same column; source table renamed/recreated while SeaTunnel job ran; schema mismatch between source snapshot and event stream.","solutions":["Verify the column actually exists in the sink schema (check the SeaTunnel catalog table definition)","If replaying CDC, start from a binlog position consistent with the current sink schema","Align the sink schema with the source (add the column, or rebuild the target table) so subsequent DROP events apply","If the drop was expected to be ignored, this warn is safe to disregard"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before applying DROP events, check membership (case-insensitive):\nboolean exists = sinkColumnNames.stream()\n    .anyMatch(c -> c.equalsIgnoreCase(dropColumn));\nif (!exists) log.warn(\"DROP ignored: column {} not in sink schema\", dropColumn);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep sink schema in sync with source table before enabling schema evolution","Start CDC from a binlog position consistent with the current sink schema","Avoid two pipelines dropping the same column concurrently","If the column is projected out of the sink, expect and ignore this warn"],"tags":["schema-evolution","cdc","file"],"backgroundTag":"schema-validation-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}