vitessio/vitess · error

column %v not found in table %v on tablet %v

Error message

column %v not found in table %v on tablet %v

What it means

After building the target select list, vdiff validates that every derived column name exists in the target table's schema (fields fetched from this tablet). If a computed/aliased column name is missing from the target table, it throws `column %v not found in table %v on tablet %v`.

Source

Thrown at go/vt/vttablet/tabletmanager/vdiff/table_plan.go:150

		}
	}
	fields := make(map[string]querypb.Type)
	for _, field := range tp.table.Fields {
		fields[strings.ToLower(field.Name)] = field.Type
	}

	targetSelect.SetSelectExprs(td.adjustForSourceTimeZone(targetSelect.GetColumns(), fields)...)
	// Start with adding all columns for comparison.
	tp.compareCols = make([]compareColInfo, sourceSelect.GetColumnCount())
	for i := range tp.compareCols {
		tp.compareCols[i].colIndex = i
		colname, err := getColumnNameForSelectExpr(targetSelect.GetColumns()[i])
		if err != nil {
			return nil, err
		}
		_, ok := fields[colname]
		if !ok {
			return nil, fmt.Errorf("column %v not found in table %v on tablet %v",
				colname, tp.table.Name, td.wd.ct.vde.thisTablet.Alias)
		}
		tp.compareCols[i].colName = colname
	}

	sourceSelect.From = sel.From
	// The target table name should the one that matched the rule.
	// It can be different from the source table.
	targetSelect.From = sqlparser.TableExprs{
		&sqlparser.AliasedTableExpr{
			Expr: &sqlparser.TableName{
				Name: sqlparser.NewIdentifierCS(tp.table.Name),
			},
		},
	}

	if len(tp.table.PrimaryKeyColumns) == 0 {
		// We use the columns from a PKE if there is one.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Compare source and target schemas (`SHOW CREATE TABLE` on both) and align them (apply the ALTER on the lagging side)
  2. Fix the workflow's filter rule so every selected/aliased column exists on the target table
  3. Re-run the vdiff after schemas converge; if using --tables, restrict the diff to tables whose schemas match
  4. Verify the tablet being used for the diff has the latest schema (run with a primary tablet that has reloaded its schema)

Example fix

// before (rule alias has no target column)
select price * qty as total from orders
// after (add column on target or select existing columns)
alter table orders add column total int; -- then select ... as total
Defensive patterns

Strategy: validation

Validate before calling

// before vdiff, check every rule column/alias exists on the target table
targetCols := map[string]bool{} // from SHOW CREATE TABLE / information_schema on target
for _, col := range ruleSelectColsAndAliases {
  if !targetCols[strings.ToLower(col)] {
    return fmt.Errorf("column %s missing on target table", col)
  }
}

Type guard

func columnsExist(cols []string, tableSchema map[string]bool) bool {
  for _, c := range cols {
    if !tableSchema[strings.ToLower(c)] { return false }
  }
  return true
}

Try / catch

tp, err := buildTablePlan(...)
if err != nil {
  if strings.Contains(err.Error(), "not found in table") {
    return fmt.Errorf("schema drift detected: %w; align source/target schemas", err)
  }
  return err
}

Prevention

When it happens

Trigger: A select expression's alias (or column) does not correspond to any actual column of the target table on the local tablet — e.g. rule selects `select a as x, b` but the target table has no column `x`; or schema drift between source and target.

Common situations: MoveTables between tables with differing schemas; adding/renaming columns mid-migration so vreplication rules reference old names; hand-edited rules with aliases that don't exist on the target; resharding where the target table schema lags.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/d86a6eac469d5a25. Report an issue: GitHub.