{"record":{"id":"e345a763d1815ed9","repo":"vitessio/vitess","slug":"found-no-possible-unique-key-on-s-whose-columns","errorCode":null,"errorMessage":"found no possible unique key on `%s` whose columns are in target table `%s`","messagePattern":"found no possible unique key on `(.+?)` whose columns are in target table `(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/schemadiff/onlineddl.go","lineNumber":563,"sourceCode":"\tanalysis.SourceSharedColumns, analysis.TargetSharedColumns, droppedSourceNonGeneratedColumns, analysis.SharedColumnsMap = AnalyzeSharedColumns(sourceColumns, targetColumns, alterTableAnalysis)\n\n\t// unique keys\n\tsourceUniqueKeys := PrioritizedUniqueKeys(sourceCreateTableEntity)\n\tif sourceUniqueKeys.Len() == 0 {\n\t\treturn nil, fmt.Errorf(\"found no possible unique key on `%s`\", sourceCreateTableEntity.Name())\n\t}\n\n\ttargetUniqueKeys := PrioritizedUniqueKeys(targetCreateTableEntity)\n\tif targetUniqueKeys.Len() == 0 {\n\t\treturn nil, fmt.Errorf(\"found no possible unique key on `%s`\", targetCreateTableEntity.Name())\n\t}\n\t// VReplication supports completely different unique keys on source and target, covering\n\t// some/completely different columns. The condition is that the key on source\n\t// must use columns which all exist on target table.\n\teligibleSourceColumnsForUniqueKey := analysis.SourceSharedColumns.Union(generatedColumns(sourceColumns))\n\tanalysis.ChosenSourceUniqueKey = IterationKeysByColumns(sourceUniqueKeys, eligibleSourceColumnsForUniqueKey).First()\n\tif analysis.ChosenSourceUniqueKey == nil {\n\t\treturn nil, fmt.Errorf(\"found no possible unique key on `%s` whose columns are in target table `%s`\", sourceCreateTableEntity.Name(), targetCreateTableEntity.Name())\n\t}\n\n\teligibleTargetColumnsForUniqueKey := analysis.TargetSharedColumns.Union(generatedColumns(targetColumns))\n\tanalysis.ChosenTargetUniqueKey = IterationKeysByColumns(targetUniqueKeys, eligibleTargetColumnsForUniqueKey).First()\n\tif analysis.ChosenTargetUniqueKey == nil {\n\t\treturn nil, fmt.Errorf(\"found no possible unique key on `%s` whose columns are in source table `%s`\", targetCreateTableEntity.Name(), sourceCreateTableEntity.Name())\n\t}\n\n\tanalysis.AddedUniqueKeys = IntroducedUniqueConstraints(sourceUniqueKeys, targetUniqueKeys, alterTableAnalysis.ColumnRenameMap)\n\tanalysis.RemovedUniqueKeys = RemovedUniqueConstraints(sourceUniqueKeys, targetUniqueKeys, alterTableAnalysis.ColumnRenameMap)\n\tanalysis.RemovedForeignKeyNames, err = RemovedForeignKeyNames(sourceCreateTableEntity, targetCreateTableEntity)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tformalizeColumns := func(columnsLists ...*ColumnDefinitionEntityList) error {\n\t\tfor _, colList := range columnsLists {\n\t\t\tfor _, col := range colList.Entities {","sourceCodeStart":545,"sourceCodeEnd":581,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/schemadiff/onlineddl.go#L545-L581","documentation":"During OnlineDDLMigrationTablesAnalysis, the source table's unique keys are filtered to those whose columns all exist in the target table (VReplication requires this so the key can be evaluated on both sides). If every source unique key references at least one column absent from the target, the analysis fails. This is a cross-table compatibility check, not a mere presence check.","triggerScenarios":"Calling OnlineDDLMigrationTablesAnalysis when the source table has unique keys but none of them is contained within analysis.SourceSharedColumns ∪ generated columns of the source — i.e. the chosen/matching target schema dropped or renamed a column used by all source unique keys.","commonSituations":"A column rename done without the rename map knowing about it; target table created from a subset of source columns; a migration that drops a column participating in the source's only unique key.","solutions":["Ensure the source's unique key columns exist on the target (add them back or keep the column)","Register the column rename in the ALTER TABLE RENAME COLUMN so shared-column analysis maps it","Choose a different source unique key whose columns are shared with the target"],"exampleFix":"-- before (target lacks 'email' used by source unique key)\nALTER TABLE t DROP COLUMN email;\n-- after\nALTER TABLE t CHANGE COLUMN email contact VARCHAR(255);","handlingStrategy":"validation","validationCode":"shared := analysis.SourceSharedColumns\nfor _, col := range chosenSourceUniqueKey.Columns { if !shared.Contains(col) { /* column missing on target */ } }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep unique-key columns shared between source and target","Always express column changes as RENAME COLUMN when renaming","Diff source/target schemas before migration"],"tags":["schemadiff","vreplication","unique-key","column-mismatch"],"backgroundTag":"missing-unique-key","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}