vitessio/vitess · error · ErrInvalidRequest

%w: SQL query is required

Error message

%w: SQL query is required

What it means

Returned by vtadmin API methods (wrapping a sentinel error) when a request omits the required SQL query text.

Source

Thrown at go/vt/vtadmin/api.go:2619

	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
	}

	// Parser with default options. New() itself initializes with default MySQL version.
	parser, err := sqlparser.New(sqlparser.Options{
		TruncateUILen:  512,
		TruncateErrLen: 0,
	})
	if err != nil {
		return nil, err

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Set req.Sql to the non-empty query to explain
  2. Validate/trim the SQL client-side before invoking the RPC
  3. Check the form/SDK path that drops the sql field

Example fix

// before
{clusterId: "prod-main", keyspace: "commerce", sql: ""}
// after
{clusterId: "prod-main", keyspace: "commerce", sql: "select * from users where id = 1"}
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(req.Sql) == "" {
    return errors.New("sql is required for vexplain")
}

Type guard

func hasSQL(req *vtadminpb.VExplainRequest) bool {
    return req != nil && strings.TrimSpace(req.Sql) != ""
}

Try / catch

if !hasSQL(req) {
    return errors.New("sql is required for vexplain")
}
resp, err := client.VExplain(ctx, req)

Prevention

When it happens

Trigger: Calling API.VExplain with ClusterId and Keyspace set but Sql equal to "".

Common situations: Text box or query builder submitted empty; query string lost in serialization (empty after trimming); template rendered without binding the SQL variable.

Related errors


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