vitessio/vitess · error
no tables in workflow %s.%s
Error message
no tables in workflow %s.%s
What it means
getWorkflowState builds the runtime state of a vreplication workflow (MoveTables/Migrate) and, for TABLES migration type, requires at least one table in the workflow since routing rules are derived from it. If ts.Tables() is empty, the workflow has no tables registered and state computation cannot proceed. Called from SwitchReads, SwitchWrites, and workflow construction.
Source
Thrown at go/vt/wrangler/traffic_switcher.go:267
// spec, so we need to use the source of the reverse workflow, which is the
// target of the workflow initiated by the user for checking routing rules.
// Similarly we use a target shard of the reverse workflow as the original
// source to check if writes have been switched.
if strings.HasSuffix(workflowName, "_reverse") {
reverse = true
// Flip the source and target keyspaces.
sourceKeyspace = state.TargetKeyspace
targetKeyspace = state.SourceKeyspace
workflowName = workflow.ReverseWorkflowName(workflowName)
} else {
sourceKeyspace = state.SourceKeyspace
}
if ts.MigrationType() == binlogdatapb.MigrationType_TABLES {
state.WorkflowType = workflow.TypeMoveTables
// We assume a consistent state, so only choose routing rule for one table.
if len(ts.Tables()) == 0 {
return nil, nil, fmt.Errorf("no tables in workflow %s.%s", targetKeyspace, workflowName)
}
table := ts.Tables()[0]
if ts.isPartialMigration { // shard level traffic switching is all or nothing
shardRoutingRules, err := wr.ts.GetShardRoutingRules(ctx)
if err != nil {
return nil, nil, err
}
rules := shardRoutingRules.Rules
for _, rule := range rules {
switch rule.ToKeyspace {
case sourceKeyspace:
state.ShardsNotYetSwitched = append(state.ShardsNotYetSwitched, rule.Shard)
case targetKeyspace:
state.ShardsAlreadySwitched = append(state.ShardsAlreadySwitched, rule.Shard)
default:
// Not a relevant rule.View on GitHub (pinned to 01a25a7d17)
Solutions
- Verify the workflow name and keyspace: `vtctldclient VReplicationExec <tablet> 'show workflows'`
- If tables were removed unintentionally, recreate the MoveTables workflow with the intended table list
- If the workflow is leftover/complete, clean it up (MoveTables Complete / Delete workflow) instead of switching traffic
- Check the `_vt.vreplication` / workflow topology records to confirm which tables the workflow covers
Example fix
// before: switching traffic on a possibly empty workflow
state, _, err := wr.getWorkflowState(ctx, targetKeyspace, workflowName)
// after: guard before switching
if len(tables(workflowName)) == 0 {
return fmt.Errorf("workflow %s.%s has no tables; check name or recreate", targetKeyspace, workflowName)
} Defensive patterns
Strategy: validation
Validate before calling
wf, err := findWorkflow(ctx, targetKeyspace, workflowName)
if err != nil {
return err
}
if len(wf.Tables) == 0 {
return fmt.Errorf("workflow %s.%s has no tables; verify name or recreate", targetKeyspace, workflowName)
} Type guard
func workflowHasTables(ts wrangler.TrafficSwitcher) bool {
return ts.MigrationType() != binlogdatapb.MigrationType_TABLES || len(ts.Tables()) > 0
} Try / catch
if _, _, err := wr.SwitchReads(ctx, targetKeyspace, workflowName, tables, direction); err != nil {
if strings.Contains(err.Error(), "no tables in workflow") {
// check `show workflows` and workflow name spelling
}
return err
} Prevention
- Verify workflow name and keyspace with `show workflows` before switching traffic
- Clean up completed/empty workflows with MoveTables Complete
- Never drop all tables from a workflow you still plan to switch
When it happens
Trigger: Calling MoveTables SwitchReads/SwitchWrites/CreateRoutingRules (or NewVReplicationWorkflow) for a workflow whose source tables list is empty — e.g. workflow created with no tables, all tables removed, or wrong workflow/keyspace name resolving to an empty table set.
Common situations: Typo in workflow name when running SwitchReads/SwitchWrites; MoveTables workflow whose tables were all dropped before traffic switch; partially-cleaned-up migration leaving an empty workflow entry; querying a keyspace that has a workflow record but no table registrations.
Related errors
- value out of range
- both atomic copy and partial mode cannot be specified for th
- invalid workflow
- multiple source keyspaces for a single workflow
- multiple target keyspaces for a single workflow
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/881ea7bae3aa6ed4.
Report an issue: GitHub.