vitessio/vitess · error

vindex name should be of the form keyspace.vindex: %s

Error message

vindex name should be of the form keyspace.vindex: %s

What it means

ExternalizeVindex requires the vindex name to be fully qualified as keyspace.vindex. Wrangler splits the argument on '.' and rejects anything that is not exactly two parts. This ensures the code can look up the correct keyspace's VSchema before mutating it.

Source

Thrown at go/vt/wrangler/materializer.go:818

	source := sqlescape.EscapeID(sourceVindexCol)
	target := sqlescape.EscapeID(vindexFromCol)

	for _, line := range lines[1:] {
		if strings.Contains(line, source) {
			line = strings.Replace(line, source, target, 1)
			line = strings.Replace(line, " AUTO_INCREMENT", "", 1)
			line = strings.Replace(line, " DEFAULT NULL", "", 1)
			return line, nil
		}
	}
	return "", fmt.Errorf("column %s not found in schema %v", sourceVindexCol, lines)
}

// ExternalizeVindex externalizes a lookup vindex that's finished backfilling or has caught up.
func (wr *Wrangler) ExternalizeVindex(ctx context.Context, qualifiedVindexName string) error {
	splits := strings.Split(qualifiedVindexName, ".")
	if len(splits) != 2 {
		return fmt.Errorf("vindex name should be of the form keyspace.vindex: %s", qualifiedVindexName)
	}
	sourceKeyspace, vindexName := splits[0], splits[1]
	sourceVSchema, err := wr.ts.GetVSchema(ctx, sourceKeyspace)
	if err != nil {
		return err
	}
	sourceVindex := sourceVSchema.Vindexes[vindexName]
	if sourceVindex == nil {
		return fmt.Errorf("vindex %s not found in vschema", qualifiedVindexName)
	}

	targetKeyspace, targetTableName, err := wr.env.Parser().ParseTable(sourceVindex.Params["table"])
	if err != nil || targetKeyspace == "" {
		return fmt.Errorf("vindex table name must be in the form <keyspace>.<table>. Got: %v", sourceVindex.Params["table"])
	}
	workflow := targetTableName + "_vdx"
	targetShards, err := wr.ts.GetServingShards(ctx, targetKeyspace)
	if err != nil {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Pass the vindex name in the form keyspace.vindex, e.g. 'commerce.corder_vdx'.
  2. Verify the string does not contain extra dots (e.g. from a fully qualified table name pasted by mistake).
  3. Check the vschema with vtctldclient GetVSchema to confirm the exact vindex key before re-running.

Example fix

// before
wr.ExternalizeVindex(ctx, "corder_vdx")
// after
wr.ExternalizeVindex(ctx, "commerce.corder_vdx")
Defensive patterns

Strategy: validation

Validate before calling

const name = "commerce.corder_vdx"
const parts = name.split(".")
if (parts.length !== 2 || !parts[0] || !parts[1]) {
  throw new Error(`vindex name must be keyspace.vindex: ${name}`)
}

Prevention

When it happens

Trigger: Calling ExternalizeVindex (via vtctldclient ExternalizeVindex / commandExternalizeVindex) with an unqualified name like 'my_vdx', or with too many dots like 'ks1.vdx.extra'.

Common situations: Typing the vindex name without its keyspace prefix in the vtctldclient command; copying an example where the vindex was referenced unqualified; programmatic callers building the name by joining strings incorrectly.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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