kataras/iris · error
binder: struct: should be a pointer to a struct value
Error message
binder: struct: should be a pointer to a struct value
What it means
makeStruct (used by container.Struct) requires a pointer to a struct so it can set fields via reflection. Passing anything else — a non-pointer struct, a pointer to non-struct, or a primitive — cannot be bound and panics.
Source
Thrown at hero/struct.go:62
}
type singletonStruct interface {
Singleton() bool
}
func isMarkedAsSingleton(structPtr any) bool {
if sing, ok := structPtr.(singletonStruct); ok && sing.Singleton() {
return true
}
return false
}
func makeStruct(structPtr any, c *Container, partyParamsCount int) *Struct {
v := valueOf(structPtr)
typ := v.Type()
if typ.Kind() != reflect.Ptr || indirectType(typ).Kind() != reflect.Struct {
panic("binder: struct: should be a pointer to a struct value")
}
isSingleton := isMarkedAsSingleton(structPtr)
disablePayloadAutoBinding := c.DisablePayloadAutoBinding
enableStructDependents := c.EnableStructDependents
disableStructDynamicBindings := c.DisableStructDynamicBindings
if isSingleton {
disablePayloadAutoBinding = true
enableStructDependents = false
disableStructDynamicBindings = true
}
// get struct's fields bindings.
bindings := getBindingsForStruct(v, c.Dependencies, c.MarkExportedFieldsAsRequired, disablePayloadAutoBinding, enableStructDependents, c.DependencyMatcher, partyParamsCount, c.Sorter)
// length bindings of 0, means that it has no fields or all mapped deps are static.
// If static then Struct.Acquire will return the same "value" instance, otherwise it will create a new one.View on GitHub (pinned to 7bedaf55a0)
Solutions
- Pass a pointer to a struct: c.Struct(&MyStruct{}).
- Verify the underlying type is actually a struct (indirectType(typ).Kind() == reflect.Struct).
- If registering the value itself, use c.Register instead of c.Struct.
Example fix
// before
c.Struct(Config{}) // value, not pointer
// after
c.Struct(&Config{}) Defensive patterns
Strategy: validation
Validate before calling
func safeStruct(c *hero.Container, v any) {
t := reflect.TypeOf(v)
if t == nil || t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
panic("Struct() requires a pointer to a struct")
}
c.Struct(v)
} Type guard
func isStructPtr(v any) bool {
t := reflect.TypeOf(v)
return t != nil && t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
} Prevention
- Always call c.Struct(&T{}), never c.Struct(T{}).
- Double-check the & for struct literals.
- Use c.Register for non-struct values.
When it happens
Trigger: c.Struct(MyStructValue{}) (value, not pointer), c.Struct(&someInt), or c.Struct(new(SomeNonStructType)) at container setup.
Common situations: Forgetting the & when passing a struct literal; passing an interface holding a non-struct; after changing the target type from struct to something else without updating the call.
Related errors
- MarkExportedFieldsAsRequired is true and at least one of str
- api container: set dependency matcher: fn cannot be nil
- bindings: unresolved: no a func type: %#+v
- expected [%d] bindings (input parameters) but got [%d] Funct
- bindings: unresolved: not a struct type: %#+v
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/0be7b4ba71f345f5.
Report an issue: GitHub.