kataras/iris · error

convert struct: invalid type: expected a struct value but go

Error message

convert struct: invalid type: expected a struct value but got: %q

What it means

convertStructToColumns only accepts reflect.Struct kinds when deriving the column map for a registered Row. Register was called with a type whose kind is not a struct (e.g. a pointer, slice, or primitive), so registration aborts with this message. It is a setup-time validation error.

Source

Thrown at x/sqlx/struct_row.go:19

package sqlx

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/kataras/iris/v12/x/reflex"
)

// DefaultTag is the default struct field tag.
var DefaultTag = "db"

// ColumnNameFunc is the function which converts a struct field name to a database column name.
type ColumnNameFunc = func(string) string

func convertStructToColumns(typ reflect.Type, nameFunc ColumnNameFunc) (map[string]*Column, error) {
	if kind := typ.Kind(); kind != reflect.Struct {
		return nil, fmt.Errorf("convert struct: invalid type: expected a struct value but got: %q", kind.String())
	}

	// Retrieve only fields valid for database.
	fields := reflex.LookupFields(typ, "")

	columns := make(map[string]*Column, len(fields))
	for i, field := range fields {
		column, ok, err := convertStructFieldToColumn(field, DefaultTag, nameFunc)
		if !ok {
			continue
		}

		if err != nil {
			return nil, fmt.Errorf("convert struct: field name: %q: %w", field.Name, err)
		}

		column.Index = i
		columns[column.Name] = column

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Pass the struct value type, not a pointer: reflect.TypeOf(User{}) not reflect.TypeOf(&User{})
  2. Dereference: for t := typ; t.Kind() == reflect.Ptr; t = t.Elem()
  3. Verify the argument is the model struct, not a DTO wrapper

Example fix

// before
row := NewRow("users", reflect.TypeOf(&User{}))
// after
row := NewRow("users", reflect.TypeOf(User{}))
Defensive patterns

Strategy: validation

Validate before calling

t := reflect.TypeOf(model)
for t != nil && t.Kind() == reflect.Ptr { t = t.Elem() }
if t == nil || t.Kind() != reflect.Struct { return errors.New("Register requires a struct type") }

Type guard

func isStructType(v any) bool {
	t := reflect.TypeOf(v)
	for t != nil && t.Kind() == reflect.Ptr { t = t.Elem() }
	return t != nil && t.Kind() == reflect.Struct
}

Prevention

When it happens

Trigger: Calling Register with a *T (pointer type), []T (slice), map, or basic type instead of the struct type T itself.

Common situations: Passing reflect.TypeOf(&User{}) instead of reflect.TypeOf(User{}); generics/reflection helpers that hand back pointer types; refactoring a struct into a type alias.

Related errors


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