{"record":{"id":"9de38a7eb29a04a9","repo":"vitessio/vitess","slug":"gettablet-v-w","errorCode":null,"errorMessage":"GetTablet(%v): %w","messagePattern":"GetTablet\\((.+?)\\): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/topo/helpers/copy.go","lineNumber":132,"sourceCode":"}\n\n// CopyTablets will create the tablets in the destination topo.\nfunc CopyTablets(ctx context.Context, fromTS, toTS *topo.Server) error {\n\tcells, err := fromTS.GetKnownCells(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fromTS.GetKnownCells: %w\", err)\n\t}\n\n\tfor _, cell := range cells {\n\t\ttabletAliases, err := fromTS.GetTabletAliasesByCell(ctx, cell)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"GetTabletsByCell(%v): %w\", cell, err)\n\t\t} else {\n\t\t\tfor _, tabletAlias := range tabletAliases {\n\t\t\t\t// read the source tablet\n\t\t\t\tti, err := fromTS.GetTablet(ctx, tabletAlias)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"GetTablet(%v): %w\", tabletAlias, err)\n\t\t\t\t}\n\n\t\t\t\t// try to create the destination\n\t\t\t\terr = toTS.CreateTablet(ctx, ti.Tablet)\n\t\t\t\tif topo.IsErrType(err, topo.NodeExists) {\n\t\t\t\t\t// update the destination tablet\n\t\t\t\t\tlog.Warn(fmt.Sprintf(\"tablet %v already exists, updating it\", tabletAlias))\n\t\t\t\t\t_, err = toTS.UpdateTabletFields(ctx, tabletAlias, func(t *topodatapb.Tablet) error {\n\t\t\t\t\t\tproto.Merge(t, ti.Tablet)\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"CreateTablet(%v): %w\", tabletAlias, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/topo/helpers/copy.go#L114-L150","documentation":"CopyTablets wraps errors from fromTS.GetTablet(ctx, tabletAlias) with the tablet alias. Aliases for the cell were listed but reading an individual Tablet record failed, aborting the copy. This happens before the destination CreateTablet/UpdateTablet steps, so the destination is untouched for that tablet.","triggerScenarios":"Calling CopyTablets when GetTablet returns NoNode (tablet deleted between listing aliases and fetching the record — common race), a per-cell topo connection failure, or unmarshal failure on a corrupt tablet record.","commonSituations":"Tablets being killed/reparented concurrently while the copy runs (vttablet shutdown, tabletmanager operations); stale tablet entries left after a cell was wiped; per-cell etcd unavailability mid-scan.","solutions":["If the wrapped cause is topo.NoNode, the tablet vanished concurrently — re-run the copy; it will pick up remaining tablets.","Verify the cell's local topo backend is healthy and reachable.","Check for corrupt tablet records at the alias path and remove/repair them in the topo backend.","Retry the copy; destination tablet creation tolerates NodeExists by updating instead."],"exampleFix":"// before\nti, err := fromTS.GetTablet(ctx, tabletAlias)\nif err != nil {\n\treturn fmt.Errorf(\"GetTablet(%v): %w\", tabletAlias, err)\n}\n// after\nti, err := fromTS.GetTablet(ctx, tabletAlias)\nif err != nil {\n\tif topo.IsErrType(err, topo.NoNode) {\n\t\tlog.Warn(fmt.Sprintf(\"tablet %v disappeared, skipping\", topoproto.TabletAliasString(tabletAlias)))\n\t\tcontinue\n\t}\n\treturn fmt.Errorf(\"GetTablet(%v): %w\", tabletAlias, err)\n}","handlingStrategy":"type-guard","validationCode":"aliases, _ := fromTS.GetTabletAliasesByCell(ctx, cell)\nfor _, a := range aliases {\n\tif _, err := fromTS.GetTablet(ctx, a); topo.IsErrType(err, topo.NoNode) {\n\t\t// stale alias; skip it in the copy run\n\t}\n}","typeGuard":"func tabletVanished(err error) bool {\n\treturn topo.IsErrType(err, topo.NoNode)\n}","tryCatchPattern":"ti, err := fromTS.GetTablet(ctx, tabletAlias)\nif err != nil {\n\tif topo.IsErrType(err, topo.NoNode) {\n\t\tcontinue\n\t}\n\treturn fmt.Errorf(\"GetTablet(%v): %w\", tabletAlias, err)\n}","preventionTips":["Pause tablet shutdown/reparent operations during tablet copies.","Treat NoNode as skip-and-continue for tablets, then re-run to converge.","Clean up stale tablet records after wiping cells or killing tablets."],"tags":["go","topo","race-condition","tablets"],"backgroundTag":"topo-node-not-found","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}