vitessio/vitess · error
schemas differ on table type for table %v: %s: %v differs f
Error message
schemas differ on table type for table %v: %s: %v differs from: %s: %v
What it means
DiffSchema compares two tablet schemas field-by-field. When two TableDefinitions with the same name have different TableDefinition.Type values (e.g. one side sees it as a base table, the other as a view), the diff is recorded via the error recorder. Internal operation tables (e.g. those created by online DDL or migration tooling) are excluded to avoid false positives.
Source
Thrown at go/vt/mysqlctl/tmutils/schema.go:258
// extra table on the right side
if left.TableDefinitions[leftIndex].Name > right.TableDefinitions[rightIndex].Name {
if !schema.IsInternalOperationTableName(right.TableDefinitions[rightIndex].Name) {
er.RecordError(fmt.Errorf("%v has an extra table named %v", rightName, right.TableDefinitions[rightIndex].Name))
}
rightIndex++
continue
}
// same name, let's see content
if left.TableDefinitions[leftIndex].Schema != right.TableDefinitions[rightIndex].Schema {
if !schema.IsInternalOperationTableName(left.TableDefinitions[leftIndex].Name) {
er.RecordError(fmt.Errorf("schemas differ on table %v:\n%s: %v\n differs from:\n%s: %v", left.TableDefinitions[leftIndex].Name, leftName, left.TableDefinitions[leftIndex].Schema, rightName, right.TableDefinitions[rightIndex].Schema))
}
}
if left.TableDefinitions[leftIndex].Type != right.TableDefinitions[rightIndex].Type {
if !schema.IsInternalOperationTableName(right.TableDefinitions[rightIndex].Name) {
er.RecordError(fmt.Errorf("schemas differ on table type for table %v:\n%s: %v\n differs from:\n%s: %v", left.TableDefinitions[leftIndex].Name, leftName, left.TableDefinitions[leftIndex].Type, rightName, right.TableDefinitions[rightIndex].Type))
}
}
leftIndex++
rightIndex++
}
for leftIndex < len(left.TableDefinitions) {
if left.TableDefinitions[leftIndex].Type == TableBaseTable {
if !schema.IsInternalOperationTableName(left.TableDefinitions[leftIndex].Name) {
er.RecordError(fmt.Errorf("%v has an extra table named %v", leftName, left.TableDefinitions[leftIndex].Name))
}
}
if left.TableDefinitions[leftIndex].Type == TableView {
er.RecordError(fmt.Errorf("%v has an extra view named %v", leftName, left.TableDefinitions[leftIndex].Name))
}
leftIndex++
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Compare the table's type on both tablets with SHOW CREATE TABLE (or SHOW FULL TABLES) and align them via ALTER TABLE / DROP+CREATE.
- Re-apply the intended schema to the lagging side using ApplySchema with allowList.
- If the mismatching table is a vitess internal operation table, confirm it is matched by schema.IsInternalOperationTableName so it can be safely ignored.
- Run vtctldclient ValidateSchema / SchemaCompare to confirm the diff is resolved before resuming the workflow.
Example fix
// before: one shard has a view, other a table SHOW FULL TABLES; -- t1: VIEW vs BASE TABLE // after: align both DROP VIEW t1; CREATE TABLE t1 (...); -- or restore from correct schema
Defensive patterns
Strategy: validation
Validate before calling
for _, l := range left.TableDefinitions {
for _, r := range right.TableDefinitions {
if l.Name == r.Name && l.Type != r.Type {
return fmt.Errorf("type mismatch on %s: %d vs %d", l.Name, l.Type, r.Type)
}
}
} Type guard
func isInternalTable(name string) bool { return schema.IsInternalOperationTableName(name) } Try / catch
err := tmutils.DiffSchemaToArray(ctx, left, right, nil)
if err != nil { log.Errorf("schema diff failed: %v", err); return err } Prevention
- Run vtctldclient ValidateSchema regularly across keyspaces
- Always deploy schema changes via ApplySchema, not direct MySQL DDL
- Include views in every ApplySchema run
- Keep backup/restore procedures version-aligned
When it happens
Trigger: Calling DiffSchema/DiffSchemaToArray on two SchemaDefinition protos where left and right both contain a table of the same name but with mismatched Type enum values; the leftIndex/rightIndex cursor has already matched names before this check.
Common situations: VDiff or resharding validation comparing schema between source and target shards; a table was converted between a view and a base table on one tablet but not the other; a restored replica diverged from the primary after a manual ALTER; schema upgrade applied to only one shard.
Related errors
- empty create database statement for %v
- empty create table statement for %v
- %v has an extra %v %v
- %v has an extra view named %v
- CopySchemaShard was not successful because the schemas betwe
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/1fbc10042bd94531.
Report an issue: GitHub.