{"record":{"id":"f298bd76e3122867","repo":"vitessio/vitess","slug":"invalid-type-transition-v-v-v","errorCode":null,"errorMessage":"invalid type transition %v: %v -> %v","messagePattern":"invalid type transition (.+?): (.+?) -> (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/vtctl.go","lineNumber":1160,"sourceCode":"\ttabletAlias, err := topoproto.ParseTabletAlias(subFlags.Arg(0))\n\tif err != nil {\n\t\treturn err\n\t}\n\tnewType, err := parseTabletType(subFlags.Arg(1), topoproto.AllTabletTypes)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tctx, cancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout)\n\tdefer cancel()\n\n\tif *dryRun {\n\t\tti, err := wr.TopoServer().GetTablet(ctx, tabletAlias)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed reading tablet %v: %v\", tabletAlias, err)\n\t\t}\n\t\tif !topo.IsTrivialTypeChange(ti.Type, newType) {\n\t\t\treturn fmt.Errorf(\"invalid type transition %v: %v -> %v\", tabletAlias, ti.Type, newType)\n\t\t}\n\t\twr.Logger().Printf(\"- %v\\n\", fmtTabletAwkable(ti))\n\t\tti.Type = newType\n\t\twr.Logger().Printf(\"+ %v\\n\", fmtTabletAwkable(ti))\n\t\treturn nil\n\t}\n\treturn wr.ChangeTabletType(ctx, tabletAlias, newType)\n}\n\nfunc commandPing(ctx context.Context, wr *wrangler.Wrangler, subFlags *pflag.FlagSet, args []string) error {\n\tif err := subFlags.Parse(args); err != nil {\n\t\treturn err\n\t}\n\tif subFlags.NArg() != 1 {\n\t\treturn errors.New(\"the <tablet alias> argument is required for the Ping command\")\n\t}\n\ttabletAlias, err := topoproto.ParseTabletAlias(subFlags.Arg(0))\n\tif err != nil {","sourceCodeStart":1142,"sourceCodeEnd":1178,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/vtctl.go#L1142-L1178","documentation":"During a dry-run ChangeTabletType, Vitess checks topo.IsTrivialTypeChange between the tablet's current type and the requested type. If the transition is not considered trivially safe to simulate/apply, this error names the alias and both types.","triggerScenarios":"Running `vtctl ChangeTabletType --dry-run <alias> <newType>` where the current→new transition is not a trivial type change — e.g. attempting to change a MASTER tablet, or a transition the command considers invalid.","commonSituations":"Scripts that attempt master changes via ChangeTabletType instead of reparent workflows; changing a BACKUP/RESTORE tablet mid-operation; automations assuming all transitions are allowed.","solutions":["Check the tablet's current type (`vtctl GetTablet <alias>`) and pick a trivially-allowed target","Use PlannedReparentShard/ EmergencyReparentShard for master transitions","Wait for BACKUP/RESTORE tablets to finish before changing type","Update automation to account for the IsTrivialTypeChange rules"],"exampleFix":"// before\nvtctl ChangeTabletType -dry-run zone1-0000000100 RDONLY   # tablet is MASTER\n// after\nvtctl PlannedReparentShard commerce/0 zone1-0000000101\nvtctl ChangeTabletType -dry-run zone1-0000000100 RDONLY\n","handlingStrategy":"validation","validationCode":"CUR=$(vtctl GetTablet -format json \"$ALIAS\" | jq -r '.type')\n# refuse non-trivial transitions up front\n[[ \"$CUR\" == \"MASTER\" ]] && { echo \"use reparent workflow, not ChangeTabletType\"; exit 1; }\n[[ \"$CUR\" == \"BACKUP\" || \"$CUR\" == \"RESTORE\" ]] && { echo \"tablet busy: $CUR\"; exit 1; }","typeGuard":null,"tryCatchPattern":"if err := runVtctl(\"ChangeTabletType\", \"--dry-run\", alias, tt); err != nil {\n    if strings.Contains(err.Error(), \"invalid type transition\") {\n        // fetch current type, choose a reparent/backup-aware path\n    }\n}","preventionTips":["Always read the tablet's current type before changing it","Route master transitions through PlannedReparentShard/EmergencyReparentShard","Avoid type changes while BACKUP/RESTORE is in progress","Simulate with --dry-run first (which is where this check fires)"],"tags":["vtctl","tablet-type","dry-run","state-transition"],"backgroundTag":"invalid-type-transition","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}