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 copies a map[string]any into a struct via reflection and must be able to write through the out parameter, so out must be a non-nil pointer. If out is not a pointer kind (e.g. a struct passed by value, or a map), it returns "out parameter must be a pointer, got %v". Passing a non-pointer would make the decode result unobservable to the caller.

Source

Thrown at tsunami/util/marshal.go:16

// Copyright 2025, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0

package util

import (
	"fmt"
	"reflect"
	"strings"
)

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

View on GitHub (pinned to a4447c1563)

Solutions

  1. Pass a pointer: MapToStruct(m, &myStruct)
  2. Ensure the variable being pointed to is the actual struct type, not a wrapped value
  3. Initialize the out variable before the call

Example fix

// before
var opts Opts
util.MapToStruct(m, opts) // value, not pointer
// after
var opts Opts
if err := util.MapToStruct(m, &opts); err != nil { return err }
Defensive patterns

Strategy: validation

Validate before calling

if out == nil || reflect.ValueOf(out).Kind() != reflect.Ptr {
    return fmt.Errorf("MapToStruct needs a pointer, got %T", out)
}

Type guard

func isStructPtr(v any) bool {
    rv := reflect.ValueOf(v)
    return rv.Kind() == reflect.Ptr && rv.Elem().Kind() == reflect.Struct
}

Try / catch

if err := util.MapToStruct(m, &opts); err != nil {
    return fmt.Errorf("decode opts failed: %w", err)
}

Prevention

When it happens

Trigger: MapToStruct(m, myStruct) (struct by value); MapToStruct(m, nil); passing an interface variable that holds a non-pointer value.

Common situations: Forgetting the & when passing a local struct; translating code from JSON-unmarshal helpers that accept values; calling through callCFunc with an output slot initialized as a value type.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/bfea53fb0fe115ec. Report an issue: GitHub.