vitessio/vitess · error

could not find vindex column %v

Error message

could not find vindex column %v

What it means

After scanning every select expression, matchColInSelect did not find the requested vindex column anywhere in the source query's select list, so the rewrite rule cannot be built. The library throws this because a vindex column must be present in the select list for routing/rewriting to work during a workflow.

Source

Thrown at go/vt/vtctl/workflow/utils.go:323

				if colExpr, ok := selExpr.Expr.(*sqlparser.ColName); ok {
					match = colExpr.Name
				} else {
					// Cannot match against a complex expression.
					continue
				}
			}
			if match.Equal(col) {
				colExpr, ok := selExpr.Expr.(*sqlparser.ColName)
				if !ok {
					return nil, fmt.Errorf("vindex column cannot be a complex expression: %v", sqlparser.String(selExpr))
				}
				return colExpr, nil
			}
		default:
			return nil, fmt.Errorf("unsupported select expression: %v", sqlparser.String(selExpr))
		}
	}
	return nil, fmt.Errorf("could not find vindex column %v", sqlparser.String(col))
}

func shouldInclude(table string, excludes []string) bool {
	// We filter out internal tables elsewhere when processing SchemaDefinition
	// structures built from the GetSchema database related API calls. In this
	// case, however, the table list comes from the user via the -tables flag
	// so we need to filter out internal table names here in case a user has
	// explicitly specified some.
	// This could happen if there's some automated tooling that creates the list of
	// tables to explicitly specify.
	// But given that this should never be done in practice, we ignore the request.
	if schema.IsInternalOperationTableName(table) {
		return false
	}
	return !slices.Contains(excludes, table)
}

// getMigrationID produces a reproducible hash based on the input parameters.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Add the vindex column to the select list of the workflow query/rule (e.g. `select id, col1 from t`).
  2. Verify the column name matches the schema and that it is the correct vindex column (check with `Show` on the table's vindexes).
  3. Regenerate the filter rules instead of hand-writing them, using the MoveTables/Reshard defaults.

Example fix

// before
rule := "select col1 from t" // vindex on id
// error: could not find vindex column id
// after
rule := "select id, col1 from t"
Defensive patterns

Strategy: validation

Validate before calling

// confirm every vindex column appears in the select list
vindexCols := []string{"id"} // from SHOW VINDEXES
for _, c := range vindexCols {
    if !strings.Contains(strings.ToLower(ruleSelectList), strings.ToLower(c)) {
        return fmt.Errorf("vindex column %s missing from select list", c)
    }
}

Prevention

When it happens

Trigger: generateRule asks matchColInSelect for column X (typically a primary-vindex column), but the select list omits it — e.g. `select col1 from t` while the vindex is on `id`; or the column name is misspelled/qualified differently.

Common situations: Hand-written filter rules missing the primary vindex column; renamed columns; case-sensitivity or keyspace-qualification mismatches between the rule and the schema.

Related errors


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