kataras/iris · error

sqlx: bind: unregistered type: %q

Error message

sqlx: bind: unregistered type: %q

What it means

Schema.Bind looks up the element type of dst in Schema.Rows, a registry populated by Register(tableName, value). If the struct type (or slice element type) was never registered, Bind cannot know the table/column mapping and returns "sqlx: bind: unregistered type: %q" with the Go type name.

Source

Thrown at x/sqlx/sqlx.go:130

}

// 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)
	}

	if expected, got := len(r.Columns), len(columnTypes); expected != got {
		return fmt.Errorf("sqlx: bind: table: %q: unexpected number of result columns: %d: expected: %d", r.Name, got, expected)
	}

	val := reflex.IndirectValue(reflect.ValueOf(dst))
	if s.AutoCloseRows {
		defer src.Close()
	}

	switch originalKind {
	case reflect.Struct:

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Register the type before querying: sqlx.Register("orders", Order{}) (or s.Register on the same Schema used by Bind).
  2. Ensure the destination element type exactly matches the registered type (same package/name).
  3. If you use a custom NewSchema, call Register on that schema, not the package-level DefaultSchema.

Example fix

// before
sqlx.Query(ctx, db, &order, "SELECT * FROM orders") // unregistered
// after
sqlx.Register("orders", Order{})
sqlx.Query(ctx, db, &order, "SELECT * FROM orders")
Defensive patterns

Strategy: validation

Validate before calling

func ensureRegistered(s *sqlx.Schema, dst any) error {
	typ := reflect.TypeOf(dst)
	for typ.Kind() == reflect.Ptr { typ = typ.Elem() }
	if typ.Kind() == reflect.Slice { typ = typ.Elem() }
	if _, ok := s.Rows[typ]; !ok {
		return fmt.Errorf("type %s not registered; call Register first", typ)
	}
	return nil
}

Type guard

func isRegistered(s *sqlx.Schema, dst any) bool {
	typ := reflect.TypeOf(dst)
	for typ.Kind() == reflect.Ptr { typ = typ.Elem() }
	if typ.Kind() == reflect.Slice { typ = typ.Elem() }
	_, ok := s.Rows[typ]
	return ok
}

Try / catch

if err := sqlx.Query(ctx, db, &order, q); err != nil {
	if strings.Contains(err.Error(), "unregistered type") {
		sqlx.Register("orders", Order{})
		err = sqlx.Query(ctx, db, &order, q)
	}
	return err
}

Prevention

When it happens

Trigger: sqlx.Query(ctx, db, &Order{}, ...) without a prior sqlx.Register("orders", Order{}) or schema.Register for that exact type; registering the type on a different Schema instance than the one used for Query.

Common situations: Forgot the init-time Register call; registered a renamed/aliased struct while querying the original; using DefaultSchema via sqlx.Register but querying a custom NewSchema().

Related errors


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