wavetermdev/waveterm · error
out parameter must be a pointer to struct, got pointer to %v
Error message
out parameter must be a pointer to struct, got pointer to %v
What it means
A second-stage guard in MapToStruct: out is a pointer, but reflect.Value.Elem() reveals it does not point to a struct (e.g. pointer to map or slice). The reflection field-walk only works on struct kinds, so the call is rejected with the pointed-to kind named.
Source
Thrown at pkg/util/utilfn/marshal.go:67
}
decoder, err := mapstructure.NewDecoder(dconfig)
if err != nil {
return err
}
return decoder.Decode(input)
}
func MapToStruct(in map[string]any, out any) error {
// Check that out is a pointer
outValue := reflect.ValueOf(out)
if outValue.Kind() != reflect.Ptr {
return fmt.Errorf("out parameter must be a pointer, got %v", outValue.Kind())
}
// Get the struct it points to
elem := outValue.Elem()
if elem.Kind() != reflect.Struct {
return fmt.Errorf("out parameter must be a pointer to struct, got pointer to %v", elem.Kind())
}
// Get type information
typ := elem.Type()
// For each field in the struct
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
// Skip unexported fields
if !field.IsExported() {
continue
}
name := getJSONName(field)
if value, ok := in[name]; ok {
if err := setValue(elem.Field(i), value); err != nil {
return fmt.Errorf("error setting field %s: %w", name, err)View on GitHub (pinned to a4447c1563)
Solutions
- Pass a pointer to a struct: MapToStruct(m, &cfg), not &m
- If the target is a **T, dereference first: MapToStruct(m, *cfgPtr)
- If you actually want a map out, use StructToMap instead — the functions are directional
- Add a Go generic constraint (out *T, T struct) so the compiler rejects wrong shapes
Example fix
// before
out := map[string]any{}
err := utilfn.MapToStruct(in, &out) // pointer to map, not struct
// after
type Config struct{ Name string `json:"name"` }
var cfg Config
err := utilfn.MapToStruct(in, &cfg) Defensive patterns
Strategy: type-guard
Validate before calling
if !isPtrToStruct(out) {
return errors.New("MapToStruct requires *struct")
} Type guard
func isPtrToStruct(out any) bool {
v := reflect.ValueOf(out)
return v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct
} Try / catch
if err := utilfn.MapToStruct(m, out); err != nil {
if strings.Contains(err.Error(), "pointer to struct") {
// destination shape is wrong; inspect %T of out
}
} Prevention
- Keep destinations as plain struct + &var, avoid **T
- Use StructToMap when the target is a map, not MapToStruct
- Add compile-time constraints or constructor helpers that enforce *struct
When it happens
Trigger: Calling MapToStruct(m, &someMap) or MapToStruct(m, &slice); passing **Config (pointer to pointer) where Elem() is a pointer, not a struct; a typed nil *Config works (Elem is struct) but a *map does not.
Common situations: Generic decode helpers receiving *map[string]any from callers who confused input and output types; refactors changing the destination type without updating MapToStruct calls; double-pointer wrapping from APIs that return *T.
Related errors
- input must be a struct or pointer to struct, got %v
- out parameter must be a pointer, got %v
- error setting field %s: %w
- cannot set value of type %v to field of type %v
- out parameter must be a pointer, got %v
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/031e85cac12fae03.
Report an issue: GitHub.