vitessio/vitess · error

lookup.Update.convert: %v

Error message

lookup.Update.convert: %v

What it means

LookupUnicodeLooseMD5Hash.Update converts new column values to the vindex's key format before delegating to the underlying lookup. If convertIds fails on the new values (e.g. a value cannot be converted to bytes/hash input), this wrapped error is returned and the update is aborted.

Source

Thrown at go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go:405

	if err != nil {
		return fmt.Errorf("lookup.Delete.vunhash: %v", err)
	}
	rowsColValues, err = convertRows(rowsColValues)
	if err != nil {
		return fmt.Errorf("lookup.Delete.convert: %v", err)
	}
	return lhu.lkp.Delete(ctx, vcursor, rowsColValues, sqltypes.NewUint64(v), vtgatepb.CommitOrder_NORMAL)
}

// Update updates the entry in the vindex table.
func (lhu *LookupUnicodeLooseMD5HashUnique) Update(ctx context.Context, vcursor VCursor, oldValues []sqltypes.Value, ksid []byte, newValues []sqltypes.Value) error {
	v, err := vunhash(ksid)
	if err != nil {
		return fmt.Errorf("lookup.Update.vunhash: %v", err)
	}
	newValues, err = convertIds(newValues)
	if err != nil {
		return fmt.Errorf("lookup.Update.convert: %v", err)
	}
	oldValues, err = convertIds(oldValues)
	if err != nil {
		return fmt.Errorf("lookup.Update.convert: %v", err)
	}
	return lhu.lkp.Update(ctx, vcursor, oldValues, ksid, sqltypes.NewUint64(v), newValues)
}

// MarshalJSON returns a JSON representation of LookupHashUnique.
func (lhu *LookupUnicodeLooseMD5HashUnique) MarshalJSON() ([]byte, error) {
	return json.Marshal(lhu.lkp)
}

// IsBackfilling implements the LookupBackfill interface
func (lhu *LookupUnicodeLooseMD5HashUnique) IsBackfilling() bool {
	return lhu.writeOnly
}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the new value's SQL type — use a text/varchar-compatible type for unicode hash vindexes.
  2. CAST the value to a compatible string type in the UPDATE statement.
  3. Verify the vindex definition in the vschema matches the column type.

Example fix

// before
UPDATE t SET email = UNHEX('...') WHERE id = 1;
// after
UPDATE t SET email = CAST(UNHEX('...') AS CHAR) WHERE id = 1;
Defensive patterns

Strategy: validation

Validate before calling

if _, err := convertIds(newValues); err != nil {
    return fmt.Errorf("new vindex values not convertible: %v", err)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "lookup.Update.convert") {
    // check column type vs vindex type; CAST values to string
}

Prevention

When it happens

Trigger: UPDATE on a table with a lookup_unicodeloosemd5_hash vindex where the new value for the vindex column cannot be converted by convertIds (unconvertible type, e.g. binary/blob value for a unicode-hash vindex).

Common situations: Updating the vindex column to a value of an unexpected SQL type (BLOB/binary) that has no string conversion; schema mismatch between the column type expected by the vindex config and the actual table column.

Related errors


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