jmoiron/sqlx · error
sqlx.bindNamedMapper: unsupported map type: %T
Error message
sqlx.bindNamedMapper: unsupported map type: %T
What it means
bindNamedMapper dispatches on the reflect.Kind of the argument: string-keyed maps go to bindMap, arrays/slices to bindArray, everything else to bindStruct. If the argument is a map whose key type is not string AND cannot be converted to map[string]interface{} (convertMapStringInterface fails), sqlx cannot bind it and reports the unsupported type. Non-string map keys have no defined named-parameter semantics.
Source
Thrown at named.go:428
func BindNamed(bindType int, query string, arg interface{}) (string, []interface{}, error) {
return bindNamedMapper(bindType, query, arg, mapper())
}
// Named takes a query using named parameters and an argument and
// returns a new query with a list of args that can be executed by
// a database. The return value uses the `?` bindvar.
func Named(query string, arg interface{}) (string, []interface{}, error) {
return bindNamedMapper(QUESTION, query, arg, mapper())
}
func bindNamedMapper(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) {
t := reflect.TypeOf(arg)
k := t.Kind()
switch {
case k == reflect.Map && t.Key().Kind() == reflect.String:
m, ok := convertMapStringInterface(arg)
if !ok {
return "", nil, fmt.Errorf("sqlx.bindNamedMapper: unsupported map type: %T", arg)
}
return bindMap(bindType, query, m)
case k == reflect.Array || k == reflect.Slice:
return bindArray(bindType, query, arg, m)
default:
return bindStruct(bindType, query, arg, m)
}
}
// NamedQuery binds a named query and then runs Query on the result using the
// provided Ext (sqlx.Tx, sqlx.Db). It works with both structs and with
// map[string]interface{} types.
func NamedQuery(e Ext, query string, arg interface{}) (*Rows, error) {
q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))
if err != nil {
return nil, err
}
return e.Queryx(q, args...)View on GitHub (pinned to 41dac167fd)
Solutions
- Convert the map to map[string]interface{} (stringify keys) before binding.
- Use a struct argument instead so bindStruct/reflectx handles field mapping.
- For slices/arrays of values, pass them as the array/slice branch expects.
- If using custom key types that are ~string, convert explicitly: m2 := make(map[string]interface{}, len(m)).
Example fix
// before
args := map[int]interface{}{1: "a"}
db.NamedExec(q, args) // unsupported map type
// after
args := map[string]interface{}{"1": "a"}
db.NamedExec(q, args) Defensive patterns
Strategy: validation
Validate before calling
func bindableMap(arg interface{}) error {
t := reflect.TypeOf(arg)
if t == nil || t.Kind() != reflect.Map {
return nil // struct/slice handled elsewhere
}
if t.Key().Kind() != reflect.String {
return fmt.Errorf("map key %s not string; convert to map[string]interface{}", t.Key())
}
return nil
} Type guard
func isStringKeyedMap(v interface{}) bool {
t := reflect.TypeOf(v)
return t != nil && t.Kind() == reflect.Map && t.Key().Kind() == reflect.String
} Try / catch
q, args, err := db.BindNamed(query, arg)
if err != nil && strings.Contains(err.Error(), "unsupported map type") {
// convert arg to map[string]interface{} and retry
return err
} Prevention
- Always pass map[string]interface{} (or msi) for map-based named binding.
- Stringify custom/named key types before binding.
- Prefer struct args for typed binding; use maps only for dynamic keys.
- Add a pre-bind validation helper in your DAO layer.
When it happens
Trigger: Passing a map with non-string keys (e.g. map[int]interface{}, map[CustomKey]T, or map with non-basic key type) to BindNamed/Named/NamedExec/NamedQuery (and their Context variants).
Common situations: Using map[int]string lookup tables as bind args; map keys defined as named string types wrapped oddly or maps the conversion helper rejects (e.g. map[interface{}]interface{} from YAML); refactored code passing a struct map with custom key struct types.
Related errors
- could not find name %s in %#v
- 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/aaab443a30358421.
Report an issue: GitHub.