vitessio/vitess · error
Error generating OnlineDDL query: %+v
Error message
Error generating OnlineDDL query: %+v
What it means
GetSchemaMigrations builds a SQL WHERE condition against the _vt.schema_migrations table based on the request's time-range filter. The query construction logic tracks an err variable, and if any step of generating the OnlineDDL query condition failed, the RPC returns this wrapped error before issuing the query.
Source
Thrown at go/vt/vtctl/grpcvtctldserver/server.go:1870
condition, err = sqlparser.ParseAndBind("migration_context=%a", sqltypes.StringBindVariable(req.MigrationContext))
case req.Status != vtctldatapb.SchemaMigration_UNKNOWN:
span.Annotate("migration_status", schematools.SchemaMigrationStatusName(req.Status))
condition, err = sqlparser.ParseAndBind("migration_status=%a", sqltypes.StringBindVariable(schematools.SchemaMigrationStatusName(req.Status)))
case req.Recent != nil:
var d time.Duration
d, _, err = protoutil.DurationFromProto(req.Recent)
if err != nil {
return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "error parsing duration: %s", err)
}
span.Annotate("recent", d.String())
condition = fmt.Sprintf("requested_timestamp > now() - interval %0.f second", d.Seconds())
default:
condition = "migration_uuid like '%'"
}
if err != nil {
return nil, fmt.Errorf("Error generating OnlineDDL query: %+v", err)
}
order := " order by `id` "
switch req.Order {
case vtctldatapb.QueryOrdering_DESCENDING:
order += "DESC"
default:
order += "ASC"
}
var skipLimit string
if req.Limit > 0 {
skipLimit = fmt.Sprintf("LIMIT %v,%v", req.Skip, req.Limit)
span.Annotate("skip_limit", skipLimit)
}
query := selectSchemaMigrationsQuery(condition, order, skipLimit)
View on GitHub (pinned to 01a25a7d17)
Solutions
- Check the underlying error detail (%+v) printed in the message
- Validate the requested time range/duration before calling (positive, finite duration)
- Simplify the request: drop the time filter or use an explicit migration_uuid list
- Ensure client protos match the server Vitess version
Example fix
// before req.TimeRange = durationpb.New(-5 * time.Minute) // after req.TimeRange = durationpb.New(24 * time.Hour)
Defensive patterns
Strategy: validation
Validate before calling
if req.TimeRange != nil && req.TimeRange.AsDuration() <= 0 {
return fmt.Errorf("TimeRange must be a positive duration")
} Type guard
func validTimeRange(tr *durationpb.Duration) bool { return tr == nil || tr.AsDuration() > 0 } Try / catch
resp, err := client.GetSchemaMigrations(ctx, req)
if err != nil && strings.Contains(err.Error(), "Error generating OnlineDDL query") {
// drop/fix the time filter and retry with a uuid list
} Prevention
- Always pass positive, finite durations for time-range filters
- Prefer filtering by explicit migration_uuid lists
- Keep client protos matched to the server version
- Test query-filter combinations against a staging cell before production
When it happens
Trigger: Calling GetSchemaMigrations where the condition-building switch leaves err set (e.g. a malformed duration in the time-range filter producing an invalid interval, per the request's TimeRange/limit settings).
Common situations: Passing a zero or negative migration interval/duration that yields a nonsensical SQL interval; client/server proto version mismatch on QueryOrdering/TimeRange fields; programmatic clients constructing odd filter combinations.
Related errors
- Foreign key found
- source and target columns must be of same length
- both atomic copy and partial mode cannot be specified for th
- invalid workflow
- multiple source keyspaces for a single workflow
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/ac7444c5da36ea3e.
Report an issue: GitHub.