wavetermdev/waveterm · error
out parameter must be a pointer, got %v
Error message
out parameter must be a pointer, got %v
What it means
MapToStruct uses reflection to copy a map[string]any into a struct, but reflection can only write through the out parameter if it is a pointer. This guard fires when out is a struct value (or any non-pointer), because writing to it would modify a copy and be lost. The error names the actual reflect.Kind received.
Source
Thrown at pkg/util/utilfn/marshal.go:61
// does a mapstructure using "json" tags
func DoMapStructure(out any, input any) error {
dconfig := &mapstructure.DecoderConfig{
Result: out,
TagName: "json",
}
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() {
continueView on GitHub (pinned to a4447c1563)
Solutions
- Pass a pointer to the destination struct: MapToStruct(m, &cfg)
- If the value is addressable already, take its address before the call
- In generic/helper wrappers, require T any with a *T argument or reflect-check and return a clear compile-time-friendly API
- Add the guard message to your lint/test expectations so regressions fail fast
Example fix
// before var cfg Config err := utilfn.MapToStruct(raw, cfg) // out parameter must be a pointer, got struct // after var cfg Config err := utilfn.MapToStruct(raw, &cfg)
Defensive patterns
Strategy: validation
Validate before calling
func checkOutPtr(out any) error {
if out == nil { return errors.New("out is nil") }
if reflect.ValueOf(out).Kind() != reflect.Ptr {
return fmt.Errorf("out must be a pointer, got %T", out)
}
return nil
} 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(), "must be a pointer") {
// fix call site: pass &dest
}
} Prevention
- Always pass &dest to MapToStruct
- Constrain helper generics to *T where possible
- Unit-test reflection helpers with wrong-type inputs
When it happens
Trigger: Calling MapToStruct(m, myStruct) passing a struct value instead of &myStruct; passing a map, slice, or interface holding a non-pointer; passing an untyped nil as out.
Common situations: Copy-paste from StructToMap call sites (which take values); forgetting the & when the destination is a local variable; wrapping generic decode helpers that accept any.
Related errors
- out parameter must be a pointer to struct, got pointer to %v
- error setting field %s: %w
- input must be a struct or pointer to struct, got %v
- 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/23b531a833db69c0.
Report an issue: GitHub.