vitessio/vitess · error

%s

Error message

%s

What it means

After ApplySchema runs on the VtctldServer, the response carries per-result messages. If any results were returned, the first one is treated as an error message and returned via fmt.Errorf with the raw result text. This surfaces schema-application failures (e.g. MySQL rejecting a DDL statement) as vtctl errors.

Source

Thrown at go/vt/vtctl/vtctl.go:2915

	}
	resp, err := wr.VtctldServer().ValidateSchemaKeyspace(ctx, &vtctldatapb.ValidateSchemaKeyspaceRequest{
		Keyspace:       keyspace,
		ExcludeTables:  excludeTableArray,
		IncludeViews:   *includeViews,
		SkipNoPrimary:  *skipNoPrimary,
		IncludeVschema: *includeVSchema,
	})
	if err != nil {
		wr.Logger().Errorf("%s\n", err.Error())
		return err
	}

	for _, result := range resp.Results {
		wr.Logger().Printf("%s\n", result)
	}

	if len(resp.Results) > 0 {
		return fmt.Errorf("%s", resp.Results[0])
	}

	return nil
}

func commandApplySchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *pflag.FlagSet, args []string) error {
	sql := subFlags.String("sql", "", "A list of semicolon-delimited SQL commands")
	sqlFile := subFlags.String("sql-file", "", "Identifies the file that contains the SQL commands")
	ddlStrategy := subFlags.String("ddl-strategy", string(schema.DDLStrategyDirect), "Online DDL strategy, compatible with @@ddl_strategy session variable (examples: 'direct', 'mysql', 'vitess --postpone-completion'")
	uuidList := subFlags.String("uuid_list", "", "Optional: comma delimited explicit UUIDs for migration. If given, must match number of DDL changes")
	migrationContext := subFlags.String("migration_context", "", "For Online DDL, optionally supply a custom unique string used as context for the migration(s) in this command. By default a unique context is auto-generated by Vitess")
	requestContext := subFlags.String("request_context", "", "synonym for --migration_context")
	waitReplicasTimeout := subFlags.Duration("wait_replicas_timeout", grpcvtctldserver.DefaultWaitReplicasTimeout, "The amount of time to wait for replicas to receive the schema change via replication.")
	batchSize := subFlags.Int64("batch_size", 0, "How many queries to batch together")

	callerID := subFlags.String("caller_id", "", "This is the effective caller ID used for the operation and should map to an ACL name which grants this identity the necessary permissions to perform the operation (this is only necessary when strict table ACLs are used)")
	if err := subFlags.Parse(args); err != nil {
		return err

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Read the error message returned — it is the MySQL/server error text from the schema application
  2. Fix the SQL in the --sql statements and retry
  3. Verify tablet health and MySQL grants, then re-run ApplySchema

Example fix

// before
--sql "ALTER TABLE customer ADD COLUMN emial VARCHAR(255)" -- error typo'd by MySQL
// after
--sql "ALTER TABLE customer ADD COLUMN email VARCHAR(255)"
Defensive patterns

Strategy: try-catch

Validate before calling

// Dry-validate SQL before ApplySchema where possible:
// run the DDL on a dev tablet or check syntax with the sqlparser

Try / catch

err := applySchema(ctx, req)
if err != nil {
  // err text is the raw server result; log it and fix the offending SQL statement
  log.Errorf("ApplySchema failed: %v", err)
}

Prevention

When it happens

Trigger: Running `vtctldclient ApplySchema` with SQL that MySQL rejects (syntax error, duplicate column, invalid charset); partial errors reported by one or more tablets propagate to the first result string.

Common situations: Applying a migration with a typo'd DDL; applying DDL that conflicts with existing schema; permission problems on the underlying MySQL.

Related errors


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