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

  1. Add or fix the struct field so every named parameter matches an exported field (or its `db` tag).
  2. Correct the query's parameter names to match struct fields.
  3. For nested values, flatten them into top-level fields or register a custom mapper.
  4. 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

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


AI-assisted analysis of jmoiron/sqlx@41dac167fd (2026-09-03). Data as JSON: /api/errors/21a5542ddeb466c6. Report an issue: GitHub.