jmoiron/sqlx · error
could not find name %s in %#v
Error message
could not find name %s in %#v
What it means
When binding a struct argument for a named query, sqlx resolves each named parameter to a struct field via TraversalsByNameFunc. If a name resolves to an empty traversal (no matching field), it cannot supply the argument and reports which name was missing and the whole argument value. This is the struct-binding counterpart of the map-binding 'missing name' error.
Source
Thrown at named.go:184
}
return bindArgs(names, arg, m)
}
// private interface to generate a list of interfaces from a given struct
// type, given a list of names to pull out of the struct. Used by public
// BindStruct interface.
func bindArgs(names []string, arg interface{}, m *reflectx.Mapper) ([]interface{}, error) {
arglist := make([]interface{}, 0, len(names))
// grab the indirected value of arg
var v reflect.Value
for v = reflect.ValueOf(arg); v.Kind() == reflect.Ptr; {
v = v.Elem()
}
err := m.TraversalsByNameFunc(v.Type(), names, func(i int, t []int) error {
if len(t) == 0 {
return fmt.Errorf("could not find name %s in %#v", names[i], arg)
}
val := reflectx.FieldByIndexesReadOnly(v, t)
arglist = append(arglist, val.Interface())
return nil
})
return arglist, err
}
// like bindArgs, but for maps.
func bindMapArgs(names []string, arg map[string]interface{}) ([]interface{}, error) {
arglist := make([]interface{}, 0, len(names))
for _, name := range names {
val, ok := arg[name]
if !ok {View on GitHub (pinned to 41dac167fd)
Solutions
- Add or fix the struct field so every named parameter matches an exported field (or its `db` tag).
- Correct the query's parameter names to match struct fields.
- For nested values, flatten them into top-level fields or register a custom mapper.
- Bind via a map[string]interface{} instead of a struct when values are not field-shaped.
Example fix
// before
q := "INSERT INTO t (a, b) VALUES (:a, :b)"
type row struct{ A string `db:"a"` } // b missing
// after
type row struct {
A string `db:"a"`
B string `db:"b"`
} Defensive patterns
Strategy: validation
Validate before calling
func structCoversNames(arg interface{}, names []string) error {
v := reflect.Indirect(reflect.ValueOf(arg))
t := v.Type()
for _, n := range names {
if _, ok := t.FieldByNameFunc(func(f reflect.StructField) bool {
tag := f.Tag.Get("db")
return f.Name == n || tag == n || strings.EqualFold(f.Name, n)
}); !ok {
return fmt.Errorf("query param %q not on struct %s", n, t.Name())
}
}
return nil
} Try / catch
q, args, err := db.BindNamed(query, structArg)
if err != nil && strings.Contains(err.Error(), "could not find name") {
// log err (it names the missing field) and fix struct/query
return err
} Prevention
- Keep named parameters and struct db tags in sync.
- Export all fields used for binding.
- Avoid nested/dotted parameter names with the default mapper.
- Add a unit test that BindNames every query against its arg type.
When it happens
Trigger: Query.Named/Exec/Get/Select with :name or ?name parameters that do not correspond to any exported field/db-tag on the passed struct.
Common situations: Typo in a named parameter vs struct field; missing `db` tag; using nested field names like user.id unsupported by default mapper; parameter named after a field that was removed/renamed.
Related errors
- sqlx.bindNamedMapper: unsupported map type: %T
- length of array is 0: %#v
- argument not a struct
- missing field
- unexpected `:` while reading named param at
AI-assisted analysis of jmoiron/sqlx@41dac167fd (2026-09-03).
Data as JSON: /api/errors/21a5542ddeb466c6.
Report an issue: GitHub.