vitessio/vitess · error · errors.Internal

no route variable found with name %s

Error message

no route variable found with name %s

What it means

VVars.GetTabletAlias in vtadmin's HTTP layer looks up a route variable by name and parses it as a TabletAlias. If the named route variable is absent from the request (wrong path template or missing parameter), it returns an errors.Internal indicating the variable was not found. This signals a routing/registration mismatch rather than bad user input.

Source

Thrown at go/vt/vtadmin/http/request.go:132

	return defaultVal, nil
}

// Vars is a mapping of the route variable values in a given request.
//
// See (gorilla/mux).Vars for details. We define a type here to add some
// additional behavior for extracting non-string values.
type Vars map[string]string

// GetTabletAlias returns the route named `key` as a TabletAlias.
//
// It returns an error if the route has no variable with that name, or if it
// cannot be parsed as a TabletAlias.
func (v Vars) GetTabletAlias(key string) (*topodatapb.TabletAlias, error) {
	aliasStr, ok := v[key]
	if !ok {
		return nil, &errors.Internal{
			Err: fmt.Errorf("no route variable found with name %s", key),
		}
	}

	alias, err := topoproto.ParseTabletAlias(aliasStr)
	if err != nil {
		return nil, &errors.BadRequest{
			Err:        err,
			ErrDetails: fmt.Sprintf("could not parse route variable %s (= %v) as tablet alias", key, aliasStr),
		}
	}

	return alias, nil
}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Ensure the route pattern declares the variable, e.g. /tablets/{cluster_id}/{alias}.
  2. Fix the key string passed to GetTabletAlias to match the route variable name exactly (case-sensitive).
  3. If the value is user-supplied and optional, use vars[key] directly and return a 400 instead of relying on GetTabletAlias.
  4. Check that the client is calling the intended endpoint that carries the alias.

Example fix

// before (route: /tablets/{cluster_id})
alias, err := vars.GetTabletAlias("alias")
// after (route: /tablets/{cluster_id}/{alias})
api.router.HandleFunc("/tablets/{cluster_id}/{alias}", api.getTablet)
alias, err := vars.GetTabletAlias("alias")
Defensive patterns

Strategy: validation

Validate before calling

if val, ok := mux.Vars(r)["alias"]; !ok || val == "" {
	http.Error(w, "missing alias path parameter", http.StatusBadRequest)
	return
}

Type guard

func hasVar(v httprouter.Params, key string) bool {
	return v.ByName(key) != ""
}

Try / catch

alias, err := vars.GetTabletAlias("alias")
if err != nil {
	var e *errors.Internal
	if stderrors.As(err, &e) {
		// route/template mismatch — fix registration, not the request
	}
	NewErrorResponse(w, err)
	return
}

Prevention

When it happens

Trigger: Calling GetTabletAlias(key) from an HTTP handler whose route does not define a `{key}` variable — e.g., handler registered for /tablet/{cluster_id} but code reads "alias"; typo between route template and key name.

Common situations: Developer adds a new handler but forgets the variable in the path pattern; copies a handler from another route with a differently named variable; client hits the wrong endpoint so no vars are populated.

Related errors


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