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
- Ensure the route pattern declares the variable, e.g. /tablets/{cluster_id}/{alias}.
- Fix the key string passed to GetTabletAlias to match the route variable name exactly (case-sensitive).
- If the value is user-supplied and optional, use vars[key] directly and return a 400 instead of relying on GetTabletAlias.
- 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
- Keep route variable names and GetTabletAlias keys in sync; define them as constants.
- Add a startup test that hits each route with sample paths to verify vars resolve.
- Review handler registrations when copying handlers between routes.
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
- http server stopped: %w
- %w: parsing %s at position %d
- must specify at least one keyspace_shard to delete (got %+v)
- invalid /throttlerlogz path
- invalid /throttlerz path
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/b08b881af86d2be3.
Report an issue: GitHub.