{"record":{"id":"dba26d28a57cc8ad","repo":"vitessio/vitess","slug":"cannot-build-vschema-for-keyspace-v-v","errorCode":null,"errorMessage":"cannot build vschema for keyspace %v: %v","messagePattern":"cannot build vschema for keyspace (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/binlog/keyspace_id_resolver.go","lineNumber":67,"sourceCode":"// keyspaceIDResolverFactory for the provided keyspace and cell.\nfunc newKeyspaceIDResolverFactory(ctx context.Context, ts *topo.Server, keyspace string, cell string, parser *sqlparser.Parser) (keyspaceIDResolverFactory, error) {\n\treturn newKeyspaceIDResolverFactoryV3(ctx, ts, keyspace, cell, parser)\n}\n\n// newKeyspaceIDResolverFactoryV3 finds the SrvVSchema in the cell,\n// gets the keyspace part, and uses it to find the column name.\nfunc newKeyspaceIDResolverFactoryV3(ctx context.Context, ts *topo.Server, keyspace string, cell string, parser *sqlparser.Parser) (keyspaceIDResolverFactory, error) {\n\tsrvVSchema, err := ts.GetSrvVSchema(ctx, cell)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tkschema, ok := srvVSchema.Keyspaces[keyspace]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"SrvVSchema has no entry for keyspace %v\", keyspace)\n\t}\n\tkeyspaceSchema, err := vindexes.BuildKeyspaceSchema(kschema, keyspace, parser)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot build vschema for keyspace %v: %v\", keyspace, err)\n\t}\n\treturn func(table *schema.Table) (int, keyspaceIDResolver, error) {\n\t\t// Find the v3 schema.\n\t\ttableSchema, ok := keyspaceSchema.Tables[table.Name.String()]\n\t\tif !ok {\n\t\t\treturn -1, nil, fmt.Errorf(\"no vschema definition for table %v\", table.Name)\n\t\t}\n\n\t\t// use the lowest cost unique vindex as the sharding key\n\t\tcolVindex, err := vindexes.FindVindexForSharding(table.Name.String(), tableSchema.ColumnVindexes)\n\t\tif err != nil {\n\t\t\treturn -1, nil, err\n\t\t}\n\n\t\t// TODO @rafael - when rewriting the mapping function, this will need to change.\n\t\t// for now it's safe to assume the sharding key will be always on index 0.\n\t\tshardingColumnName := colVindex.Columns[0].String()\n\t\tfor i, col := range table.Fields {","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/binlog/keyspace_id_resolver.go#L49-L85","documentation":"After finding the keyspace entry in SrvVSchema, the resolver builds a full keyspace schema via vindexes.BuildKeyspaceSchema. If the vschema definition is invalid (bad vindex types, malformed tables), streaming fails with the underlying build error wrapped.","triggerScenarios":"StreamKeyRange on a keyspace whose SrvVSchema entry has invalid vindex definitions or malformed table/vindex configuration.","commonSituations":"Typo in vindex type name in the vschema JSON; vindex referencing a non-existent column-owner table; incompatible vschema after a migration.","solutions":["Read the wrapped '%v' inner error for the exact vschema problem.","Fix the keyspace vschema (vtctldclient ApplyVSchema) — validate the JSON locally first.","Rebuild SrvVSchema (RebuildKeyspaceGraph) after correcting, then retry the stream."],"exampleFix":"// before (invalid vindex type)\n{\"vindexes\":{\"h\":{\"type\":\"hashhh\"}}}\n// after\n{\"vindexes\":{\"h\":{\"type\":\"hash\"}}}","handlingStrategy":"validation","validationCode":"var vs map[string]any\nif err := json.Unmarshal(vschemaJSON, &vs); err != nil {\n\treturn fmt.Errorf(\"invalid vschema JSON: %w\", err)\n}\n// validate vindex types exist before applying\nfor name, vi := range vs[\"vindexes\"].(map[string]any) {\n\tt := vi.(map[string]any)[\"type\"]\n\tif !knownVindexTypes[t.(string)] {\n\t\treturn fmt.Errorf(\"unknown vindex type %s for %s\", t, name)\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := updateStream.StreamKeyRange(ctx, ...); err != nil {\n\tif strings.Contains(err.Error(), \"cannot build vschema\") {\n\t\tlog.Error(\"fix vschema via vtctldclient ApplyVSchema\", slog.Any(\"error\", err))\n\t}\n\treturn err\n}","preventionTips":["Validate vschema JSON (vtctldclient ApplyVSchema does server-side validation) before streaming.","Keep vindex type names correct; check the vindexes package list.","Re-run RebuildKeyspaceGraph after every ApplyVSchema."],"tags":["vschema","vindex","binlog","config"],"backgroundTag":"vschema-build-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}