kataras/iris · error

sqlx: bind: destination not a pointer

Error message

sqlx: bind: destination not a pointer

What it means

Schema.Bind reflects on dst to discover the target struct or slice-of-struct type. If dst is not a pointer (e.g. a struct value or a struct passed by value), reflection cannot write results into it, so Bind returns "sqlx: bind: destination not a pointer" before touching the rows.

Source

Thrown at x/sqlx/sqlx.go:118

func (s *Schema) Query(ctx context.Context, db *sql.DB, dst any, query string, args ...any) error {
	rows, err := db.QueryContext(ctx, query, args...)
	if err != nil {
		return err
	}

	if !s.AutoCloseRows { // if not close on bind, we must close it here.
		defer rows.Close()
	}

	err = s.Bind(dst, rows)
	return err
}

// Bind sets "dst" to the result of "src" and reports any errors.
func (s *Schema) Bind(dst any, src *sql.Rows) error {
	typ := reflect.TypeOf(dst)
	if typ.Kind() != reflect.Ptr {
		return fmt.Errorf("sqlx: bind: destination not a pointer")
	}

	typ = typ.Elem()

	originalKind := typ.Kind()
	if typ.Kind() == reflect.Slice {
		typ = typ.Elem()
	}

	r, ok := s.Rows[typ]
	if !ok {
		return fmt.Errorf("sqlx: bind: unregistered type: %q", typ.String())
	}

	columnTypes, err := src.ColumnTypes()
	if err != nil {
		return fmt.Errorf("sqlx: bind: table: %q: %w", r.Name, err)
	}

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Pass a pointer: sqlx.Query(ctx, db, &user, query) or &users for a slice.
  2. If dst comes from an interface, ensure it was initialized as a pointer (reflect.New(typ).Interface()).
  3. Add a compile-time helper or lint to require pointer receivers for scan destinations.

Example fix

// before
var user User
sqlx.Query(ctx, db, user, "SELECT * FROM users LIMIT 1") // error
// after
sqlx.Query(ctx, db, &user, "SELECT * FROM users LIMIT 1")
Defensive patterns

Strategy: validation

Validate before calling

func ensurePtr(dst any) error {
	if reflect.TypeOf(dst).Kind() != reflect.Ptr {
		return errors.New("sqlx: bind: destination not a pointer")
	}
	return nil
}
// call before sqlx.Query / Bind

Type guard

func isPointer(dst any) bool { return reflect.TypeOf(dst).Kind() == reflect.Ptr }

Try / catch

if err := sqlx.Query(ctx, db, &user, query); err != nil {
	if err.Error() == "sqlx: bind: destination not a pointer" {
		return fmt.Errorf("pass &user (a pointer) as dst: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: sqlx.Query(ctx, db, User{}, ...) or s.Bind(User{}, rows) — passing a struct value instead of &user / &users.

Common situations: Forgetting & in the dst argument; capturing the struct in a variable typed as any holding a non-pointer; refactors that drop the address-of operator.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/b6d38aff38489b6f. Report an issue: GitHub.