vitessio/vitess · error · ErrInvalidRequest
%w: clusterID is required
Error message
%w: clusterID is required
What it means
VExplain validates the request before executing; an empty cluster_id fails with ErrInvalidRequest wrapped by this message. It is a pure client-input validation error — no cluster lookup or query occurs.
Source
Thrown at go/vt/vtadmin/api.go:2611
res, err := c.Vtctld.ValidateVersionShard(ctx, &vtctldatapb.ValidateVersionShardRequest{
Keyspace: req.Keyspace,
Shard: req.Shard,
})
if err != nil {
return nil, err
}
return res, nil
}
// VExplain is part of the vtadminpb.VTAdminServer interface.
func (api *API) VExplain(ctx context.Context, req *vtadminpb.VExplainRequest) (*vtadminpb.VExplainResponse, error) {
span, ctx := trace.NewSpan(ctx, "API.VExplain")
defer span.Finish()
if req.ClusterId == "" {
return nil, fmt.Errorf("%w: clusterID is required", errors.ErrInvalidRequest)
}
if req.Keyspace == "" {
return nil, fmt.Errorf("%w: keyspace name is required", errors.ErrInvalidRequest)
}
if req.Sql == "" {
return nil, fmt.Errorf("%w: SQL query is required", errors.ErrInvalidRequest)
}
c, err := api.getClusterForRequest(req.ClusterId)
if err != nil {
return nil, err
}
if !api.authz.IsAuthorized(ctx, c.ID, rbac.VExplainResource, rbac.GetAction) {
return nil, nil
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Set ClusterId to a valid registered cluster ID in the VExplainRequest before sending
- Check client code that builds the request for a dropped/renamed field
- Validate required fields client-side before issuing the RPC
Example fix
// before
req := &vtadminpb.VExplainRequest{Keyspace: "ks", Sql: q}
// after
req := &vtadminpb.VExplainRequest{ClusterId: "prod-main", Keyspace: "ks", Sql: q} Defensive patterns
Strategy: validation
Validate before calling
func validateVExplainRequest(clusterID, keyspace, sql string) error {
if clusterID == "" {
return errors.New("clusterID is required")
}
if keyspace == "" {
return errors.New("keyspace is required")
}
if sql == "" {
return errors.New("sql is required")
}
return nil
} Type guard
func vExplainRequestValid(req *vtadminpb.VExplainRequest) bool {
return req != nil && req.ClusterId != "" && req.Keyspace != "" && req.Sql != ""
} Try / catch
if err := validateVExplainRequest(req.ClusterId, req.Keyspace, req.Sql); err != nil {
return err
}
resp, err := client.VExplain(ctx, req) Prevention
- Always construct VExplainRequest with all three fields from a shared helper
- Validate required fields at the client boundary before RPC calls
- Keep request builders typed/structured instead of hand-built maps
When it happens
Trigger: Calling API.VExplain with a VExplainRequest whose ClusterId field is the empty string.
Common situations: Client SDK constructed the request without setting ClusterId; UI passed only keyspace/sql; migrating from VTExplain (which uses req.Cluster) to VExplain and forgetting to rename/populate the field.
Related errors
- %w: keyspace name is required
- %w: SQL query is required
- %w: cluster ID is required
- %w: %s
- %w: request cannot be nil
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/f22e8071ec442d02.
Report an issue: GitHub.