{"record":{"id":"4b09804394c947ae","repo":"vitessio/vitess","slug":"columnvindex-for-table-v-already-exists-v-plea","errorCode":null,"errorMessage":"ColumnVindex for table %v already exists: %v, please remove it and try again","messagePattern":"ColumnVindex for table (.+?) already exists: (.+?), please remove it and try again","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/wrangler/materializer.go","lineNumber":645,"sourceCode":"\t\t}\n\t}\n\tsourceVSchemaTable = sourceVSchema.Tables[sourceTableName]\n\tif sourceVSchemaTable == nil {\n\t\tif !schema.IsInternalOperationTableName(sourceTableName) {\n\t\t\treturn nil, nil, nil, fmt.Errorf(\"source table %s not found in vschema\", sourceTableName)\n\t\t}\n\t}\n\tfor _, colVindex := range sourceVSchemaTable.ColumnVindexes {\n\t\t// For a conflict, the vindex name and column should match.\n\t\tif colVindex.Name != vindexName {\n\t\t\tcontinue\n\t\t}\n\t\tcolName := colVindex.Column\n\t\tif len(colVindex.Columns) != 0 {\n\t\t\tcolName = colVindex.Columns[0]\n\t\t}\n\t\tif colName == sourceVindexColumns[0] {\n\t\t\treturn nil, nil, nil, fmt.Errorf(\"ColumnVindex for table %v already exists: %v, please remove it and try again\", sourceTableName, colName)\n\t\t}\n\t}\n\n\t// Validate against source schema\n\tsourceShards, err := wr.ts.GetServingShards(ctx, keyspace)\n\tif err != nil {\n\t\treturn nil, nil, nil, err\n\t}\n\tonesource := sourceShards[0]\n\tif onesource.PrimaryAlias == nil {\n\t\treturn nil, nil, nil, fmt.Errorf(\"source shard has no primary: %v\", onesource.ShardName())\n\t}\n\treq := &tabletmanagerdatapb.GetSchemaRequest{Tables: []string{sourceTableName}}\n\ttableSchema, err := schematools.GetSchema(ctx, wr.ts, wr.tmc, onesource.PrimaryAlias, req)\n\tif err != nil {\n\t\treturn nil, nil, nil, err\n\t}\n\tif len(tableSchema.TableDefinitions) != 1 {","sourceCodeStart":627,"sourceCodeEnd":663,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/wrangler/materializer.go#L627-L663","documentation":"While attaching the new lookup vindex to the source table, Vitess scans existing ColumnVindexes. If one already exists whose vindex name matches but whose first column equals the source vindex column being used, creation is blocked because the same column cannot carry the vindex mapping twice.","triggerScenarios":"The source table's vschema already has a ColumnVindex referencing the same vindex name AND same first column as the new lookup vindex's source columns — e.g. from a previous CreateLookupVindex run that was not rolled back.","commonSituations":"Retrying a failed/partial CreateLookupVindex that already appended the ColumnVindex; manually adding the vindex to the vschema before running the command; leftover state from an aborted backfill.","solutions":["Remove the existing ColumnVindex entry for that column/vindex from the source table in the vschema and retry (`vtctldclient ApplyVSchema`)","If a prior CreateLookupVindex partially completed, clean up its vschema changes (and lookup table/workflow) before re-running","Choose a different source column if a second lookup on the same table is intended"],"exampleFix":"// before\n\"column_vindexes\": [{\"name\":\"user_lookup\",\"column\":\"user_id\"}, {\"name\":\"user_lookup\",\"column\":\"user_id\"}]\n// after: remove the duplicate entry\n\"column_vindexes\": [{\"name\":\"user_lookup\",\"column\":\"user_id\"}]","handlingStrategy":"validation","validationCode":"for _, cv := range sourceVSchemaTable.ColumnVindexes {\n    if cv.Name == vindexName && firstCol(cv) == sourceVindexColumns[0] {\n        return fmt.Errorf(\"remove existing ColumnVindex on %s first\", sourceTableName)\n    }\n}","typeGuard":"func duplicateColumnVindex(tbl *vschemapb.Table, name, col string) bool {\n    for _, cv := range tbl.ColumnVindexes {\n        c := cv.Column\n        if len(cv.Columns) > 0 { c = cv.Columns[0] }\n        if cv.Name == name && c == col { return true }\n    }\n    return false\n}","tryCatchPattern":"if err := createLookupVindex(...); err != nil {\n    if strings.Contains(err.Error(), \"ColumnVindex for table\") {\n        return cleanUpPartialVindex(ks, table, vindexName) // remove and retry\n    }\n    return err\n}","preventionTips":["After any failed CreateLookupVindex, check the vschema for partially-applied ColumnVindexes before retrying","Don't manually pre-add the vindex to the vschema — let CreateLookupVindex do it","Keep one lookup vindex per (vindex, first-column) pair per table"],"tags":["vitess","vschema","vindex","conflict"],"backgroundTag":"vschema-name-conflict","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}