{"record":{"id":"e894259b21243136","repo":"vitessio/vitess","slug":"getkeyspace-v-w","errorCode":null,"errorMessage":"GetKeyspace(%v): %w","messagePattern":"GetKeyspace\\((.+?)\\): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/topo/helpers/copy.go","lineNumber":46,"sourceCode":"\t\"vitess.io/vitess/go/vt/sqlparser\"\n\t\"vitess.io/vitess/go/vt/topo\"\n\t\"vitess.io/vitess/go/vt/topo/topoproto\"\n\t\"vitess.io/vitess/go/vt/vtgate/vindexes\"\n\n\ttopodatapb \"vitess.io/vitess/go/vt/proto/topodata\"\n)\n\n// CopyKeyspaces will create the keyspaces in the destination topo.\nfunc CopyKeyspaces(ctx context.Context, fromTS, toTS *topo.Server, parser *sqlparser.Parser) error {\n\tkeyspaces, err := fromTS.GetKeyspaces(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"GetKeyspaces: %w\", err)\n\t}\n\n\tfor _, keyspace := range keyspaces {\n\t\tki, err := fromTS.GetKeyspace(ctx, keyspace)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"GetKeyspace(%v): %w\", keyspace, err)\n\t\t}\n\n\t\tif err := toTS.CreateKeyspace(ctx, keyspace, ki.Keyspace); err != nil {\n\t\t\tif topo.IsErrType(err, topo.NodeExists) {\n\t\t\t\tlog.Warn(fmt.Sprintf(\"keyspace %v already exists\", keyspace))\n\t\t\t} else {\n\t\t\t\tlog.Error(fmt.Sprintf(\"CreateKeyspace(%v): %v\", keyspace, err))\n\t\t\t}\n\t\t}\n\n\t\tksvs, err := fromTS.GetVSchema(ctx, keyspace)\n\t\tswitch {\n\t\tcase err == nil:\n\t\t\t_, err = vindexes.BuildKeyspace(ksvs.Keyspace, parser)\n\t\t\tif err != nil {\n\t\t\t\tlog.Error(fmt.Sprintf(\"BuildKeyspace(%v): %v\", keyspace, err))\n\t\t\t\tbreak\n\t\t\t}","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/topo/helpers/copy.go#L28-L64","documentation":"CopyKeyspaces wraps errors from fromTS.GetKeyspace(ctx, keyspace) with the failing keyspace name. The keyspace listing succeeded but reading an individual keyspace record failed. NodeExists on the destination is tolerated with a warning; only errors reading the source abort the copy.","triggerScenarios":"Calling CopyKeyspaces when GetKeyspace returns topo.NoNode (keyspace deleted between list and get — a race), a connection error to the source topo, or a corrupt/partial keyspace record that fails unmarshaling.","commonSituations":"Concurrent topology modification (keyspace removed by a reshard/vtctld operation while the copy runs); stale topo cache; etcd compaction; ACL denying read on a specific keyspace node.","solutions":["Check the wrapped error type: if topo.NoNode, the keyspace vanished concurrently — re-run the copy after the conflicting operation finishes.","Verify read permissions on the keyspace node in the source topo.","Check source topo backend health if the error is a connection/timeout error.","Re-run CopyKeyspaces; the operation is idempotent (existing keyspaces are skipped with a warning)."],"exampleFix":"// before\nif err != nil {\n\treturn fmt.Errorf(\"GetKeyspace(%v): %w\", keyspace, err)\n}\n// after\nif err != nil {\n\tif topo.IsErrType(err, topo.NoNode) {\n\t\tlog.Warn(fmt.Sprintf(\"keyspace %v disappeared, skipping\", keyspace))\n\t\tcontinue\n\t}\n\treturn fmt.Errorf(\"GetKeyspace(%v): %w\", keyspace, err)\n}","handlingStrategy":"type-guard","validationCode":"_, err := fromTS.GetKeyspace(ctx, ks)\nif topo.IsErrType(err, topo.NoNode) {\n\t// keyspace already gone; safe to skip or re-list\n}","typeGuard":"func keyspaceGone(err error) bool {\n\treturn topo.IsErrType(err, topo.NoNode)\n}","tryCatchPattern":"ki, err := fromTS.GetKeyspace(ctx, keyspace)\nif err != nil {\n\tif topo.IsErrType(err, topo.NoNode) {\n\t\tcontinue\n\t}\n\treturn fmt.Errorf(\"GetKeyspace(%v): %w\", keyspace, err)\n}","preventionTips":["Avoid running copies while vtctld reshard/delete operations are in flight.","Re-list keyspaces immediately before reading each record to narrow the race window.","Use topo.IsErrType(err, topo.NoNode) to distinguish races from real failures."],"tags":["go","topo","race-condition"],"backgroundTag":"topo-node-not-found","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}