vitessio/vitess · error

Found DROP CONSTRAINT: %v, but could not find constraint nam

Error message

Found DROP CONSTRAINT: %v, but could not find constraint name in map

What it means

When rewriting a diffed ALTER/CREATE statement for Online DDL, the code maps renamed constraint names through constraintMap. A DROP CHECK / FOREIGN KEY / CONSTRAINT statement references a constraint name not present in the map, so the statement cannot be translated to the target's constraint naming. This indicates an internal inconsistency between the rename map and the parsed statements.

Source

Thrown at go/vt/schemadiff/onlineddl.go:676

// ValidateAndEditAlterTableStatement inspects the AlterTable statement and:
// - modifies any CONSTRAINT name according to given name mapping
// - explode ADD FULLTEXT KEY into multiple statements
func ValidateAndEditAlterTableStatement(originalTableName string, baseUUID string, capableOf capabilities.CapableOf, alterTable *sqlparser.AlterTable, constraintMap map[string]string) (alters []*sqlparser.AlterTable, err error) {
	capableOfInstantDDLXtrabackup, err := capableOf(capabilities.InstantDDLXtrabackupCapability)
	if err != nil {
		return nil, err
	}

	hashExists := map[string]bool{}
	validateWalk := func(node sqlparser.SQLNode) (kontinue bool, err error) {
		switch node := node.(type) {
		case *sqlparser.DropKey:
			if node.Type == sqlparser.CheckKeyType || node.Type == sqlparser.ForeignKeyType || node.Type == sqlparser.ConstraintType {
				// drop a check or a foreign key constraint
				mappedName, ok := constraintMap[node.Name.String()]
				if !ok {
					return false, fmt.Errorf("Found DROP CONSTRAINT: %v, but could not find constraint name in map", sqlparser.CanonicalString(node))
				}
				node.Name = sqlparser.NewIdentifierCI(mappedName)
			}
		case *sqlparser.AddConstraintDefinition:
			oldName := node.ConstraintDefinition.Name.String()
			newName := newConstraintName(originalTableName, baseUUID, node.ConstraintDefinition, hashExists, sqlparser.CanonicalString(node.ConstraintDefinition.Details), oldName)
			node.ConstraintDefinition.Name = sqlparser.NewIdentifierCI(newName)
			constraintMap[oldName] = newName
		}
		return true, nil
	}
	if err := sqlparser.Walk(validateWalk, alterTable); err != nil {
		return alters, err
	}
	alters = append(alters, alterTable)
	// Handle ADD FULLTEXT KEY statements
	countAddFullTextStatements := 0
	redactedOptions := make([]sqlparser.AlterOption, 0, len(alterTable.AlterOptions))

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Report/verify the diff generation: the constraint rename map should include all dropped constraint names — this may be a schemadiff bug
  2. Regenerate the schema diff from the current actual schemas so the map and statements are consistent
  3. Drop and re-add the constraint explicitly in the migration so the name mapping is unnecessary

Example fix

// before: drop by stale name not in map
ALTER TABLE t DROP FOREIGN KEY fk_old;
// after: drop and re-add so naming is explicit
ALTER TABLE t DROP FOREIGN KEY fk_old, ADD CONSTRAINT fk_new FOREIGN KEY (a) REFERENCES p(id);
Defensive patterns

Strategy: try-catch

Validate before calling

for _, name := range droppedConstraintNames { if _, ok := constraintMap[name]; !ok { return fmt.Errorf("constraint %q not in rename map", name) } }

Try / catch

if err != nil {
  if strings.Contains(err.Error(), "could not find constraint name in map") {
    // regenerate the diff from current schemas or file a bug
  }
}

Prevention

When it happens

Trigger: Applying a diff containing `ALTER TABLE ... DROP CONSTRAINT/FOREIGN KEY/CHECK <name>` where constraintMap (built from the table's rename analysis) lacks that name.

Common situations: Renaming a table whose foreign-key constraints were renamed by a previous migration; a schema diff generated against a differently-named constraint set; partial migrations applied out of order.

Related errors


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