vitessio/vitess · error · ErrWorkflowCompleteNotFullySwitched
cannot complete workflow because you have not yet switched a
Error message
cannot complete workflow because you have not yet switched all read and write traffic
What it means
MoveTablesComplete refuses to finalize a MoveTables workflow when read and write traffic has not yet been fully switched to the target keyspace. Completing early would drop replication while the source still serves traffic, losing writes. The sentinel ErrWorkflowCompleteNotFullySwitched makes this state explicit to callers.
Source
Thrown at go/vt/vtctl/workflow/server.go:127
// Time to wait between LOCK TABLES cycles on the sources during SwitchWrites.
lockTablesCycleDelay = time.Duration(100 * time.Millisecond)
SqlUnfreezeWorkflow = "update _vt.vreplication set state='Running', message='' where db_name=%a and workflow=%a"
)
var (
// ErrInvalidWorkflow is a catchall error type for conditions that should be
// impossible when operating on a workflow.
ErrInvalidWorkflow = errors.New("invalid workflow")
// ErrMultipleSourceKeyspaces occurs when a workflow somehow has multiple
// source keyspaces across different shard primaries. This should be
// impossible.
ErrMultipleSourceKeyspaces = errors.New("multiple source keyspaces for a single workflow")
// ErrMultipleTargetKeyspaces occurs when a workflow somehow has multiple
// target keyspaces across different shard primaries. This should be
// impossible.
ErrMultipleTargetKeyspaces = errors.New("multiple target keyspaces for a single workflow")
ErrWorkflowCompleteNotFullySwitched = errors.New("cannot complete workflow because you have not yet switched all read and write traffic")
ErrWorkflowDeleteWritesSwitched = errors.New("cannot delete workflow because you have already switched write traffic")
)
// Server provides an API to work with Vitess workflows, like vreplication
// workflows (MoveTables, Reshard, etc) and schema migration workflows.
type Server struct {
ts *topo.Server
tmc tmclient.TabletManagerClient
// Limit the number of concurrent background goroutines if needed.
sem *semaphore.Weighted
env *vtenv.Environment
options serverOptions
}
// NewServer returns a new server instance with the given topo.Server and
// TabletManagerClient.
func NewServer(env *vtenv.Environment, ts *topo.Server, tmc tmclient.TabletManagerClient, opts ...ServerOption) *Server {
s := &Server{View on GitHub (pinned to 01a25a7d17)
Solutions
- Run `SwitchReads -tablet_type=rdonly,replica` and then `SwitchReads -tablet_type=primary` for the workflow.
- Run `SwitchWrites` (or MigrateTraffic) to completion, confirming all writes are served by the target.
- Re-run MoveTablesComplete only after `Workflow Show` confirms all traffic is switched.
Example fix
// before vtctldclient MoveTablesComplete --workflow sales commerce // error: not yet switched all traffic // after vtctldclient SwitchReads --tablet_type=replica commerce.sales vtctldclient SwitchWrites --shard 0 commerce.sales vtctldclient MoveTablesComplete --workflow sales commerce
Defensive patterns
Strategy: validation
Validate before calling
state, _ := client.GetWorkflowState(ctx, targetKeyspace, workflow)
if !state.AllTrafficSwitched() {
return fmt.Errorf("switch reads and writes before completing %s", workflow)
} Try / catch
if err := client.MoveTablesComplete(ctx, ks, wf); err != nil {
if errors.Is(err, workflow.ErrWorkflowCompleteNotFullySwitched) {
return fmt.Errorf("run SwitchReads + SwitchWrites for %s first: %w", wf, err)
}
return err
} Prevention
- Always run SwitchReads (rdonly, replica, primary) then SwitchWrites before complete
- Confirm with Workflow Show that all traffic is on the target
- Script the cutover as an ordered pipeline rather than manual steps
When it happens
Trigger: Calling MoveTablesComplete (vtctldserver Workflow complete) before `SwitchReads` and `SwitchWrites`/`MigrateTraffic` have moved all traffic for every table in the workflow.
Common situations: Operators running the final cutover step too early in a MoveTables migration, or some tables' read traffic still routed to the source after a partial switch.
Related errors
- cannot delete workflow because you have already switched wri
- no streams found
- no sharded vschema was provided, so you will need to update
- failed to successfully refresh all tablets in the %s/%s sour
- failed to successfully refresh all tablets in the %s/%s targ
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/22fcba5649d8d070.
Report an issue: GitHub.