kataras/iris · error
sqlx: bind: table: %q: unexpected destination kind: %q
Error message
sqlx: bind: table: %q: unexpected destination kind: %q
What it means
Bind maps query results into a destination via reflection and supports only specific destination kinds (pointer-to-struct, pointer-to-slice-of-struct, and similar scan targets). Passing a dst whose reflected kind falls outside the switch's handled cases hits the default branch and returns this error. It is a programmer-API misuse, not a data problem.
Source
Thrown at x/sqlx/sqlx.go:175
return src.Err()
case reflect.Slice:
for src.Next() {
elem := reflect.New(typ).Elem()
if err = r.bindSingle(typ, elem, columnTypes, src); err != nil {
return err
}
val = reflect.Append(val, elem)
}
if err = src.Err(); err != nil {
return err
}
reflect.ValueOf(dst).Elem().Set(val)
return nil
default:
return fmt.Errorf("sqlx: bind: table: %q: unexpected destination kind: %q", r.Name, typ.Kind().String())
}
}
func (r *Row) bindSingle(typ reflect.Type, val reflect.Value, columnTypes []*sql.ColumnType, scanner interface{ Scan(...any) error }) error {
fieldPtrs, err := r.lookupStructFieldPtrs(typ, val, columnTypes)
if err != nil {
return fmt.Errorf("sqlx: bind: table: %q: %w", r.Name, err)
}
return scanner.Scan(fieldPtrs...)
}
func (r *Row) lookupStructFieldPtrs(typ reflect.Type, val reflect.Value, columnTypes []*sql.ColumnType) ([]any, error) {
fieldPtrs := make([]any, 0, len(columnTypes))
for _, columnType := range columnTypes {
columnName := columnType.Name()
tableColumn, ok := r.Columns[columnName]View on GitHub (pinned to 7bedaf55a0)
Solutions
- Pass a *Struct or *[]Struct as dst
- Dereference double pointers before calling
- Check that dst is not nil
- If scanning a scalar, use the raw database/sql Rows.Scan instead of Bind
Example fix
// before var user *User err := db.Query(row, &user, "SELECT ...") // after var user User err := db.Query(row, &user, "SELECT ...")
Defensive patterns
Strategy: type-guard
Validate before calling
if dst == nil || reflect.TypeOf(dst).Kind() != reflect.Ptr { return errors.New("dst must be a pointer to struct or slice") } Type guard
func isBindableDst(dst any) bool {
t := reflect.TypeOf(dst)
if t == nil || t.Kind() != reflect.Ptr { return false }
e := t.Elem()
return e.Kind() == reflect.Struct || e.Kind() == reflect.Slice
} Try / catch
if err := db.Query(row, dst, q); err != nil { if strings.Contains(err.Error(), "unexpected destination kind") { return fmt.Errorf("bad dst %T: %w", dst, err) } return err } Prevention
- Always pass &struct or &[]struct
- Avoid double pointers and pre-declared pointer variables
- Add unit tests covering each destination shape
When it happens
Trigger: Passing a non-pointer, a pointer to a map, a pointer to a primitive (e.g. *int where a struct/slice is expected), or a **struct (double pointer) as dst to Query/Bind.
Common situations: Copying code from database/sql style scans into sqlx Bind; accidentally passing &userSlice where userSlice is already a pointer; passing nil interface.
Related errors
- context: read body: cannot bind multipart/related: use ReadM
- sqlx: bind: destination not a pointer
- convert struct: invalid type: expected a struct value but go
- bindings: unresolved: no a func type: %#+v
- bindings: unresolved: not a struct type: %#+v
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/909bce93fbf48122.
Report an issue: GitHub.