hyperledger/fabric · error
supplied output argument must be a pointer to a struct, but
Error message
supplied output argument must be a pointer to a struct, but it is pointer to something else
What it means
After confirming output is a pointer, EnhancedExactUnmarshal checks that the pointed-to element type is a struct, since it builds leaf keys from the struct's fields via getKeysRecursively. A pointer to anything else (map, slice, string) cannot be reflected into the exact-key unmarshal machinery, so this error is returned.
Source
Thrown at common/viperutil/config_util.go:385
err := mapstructure.WeakDecode(data, config)
if err != nil {
return nil, errors.Wrap(err, "could not decode bccsp type")
}
return config, nil
}
// EnhancedExactUnmarshal is intended to unmarshal a config file into a structure
// producing error when extraneous variables are introduced and supporting
// the time.Duration type
func (c *ConfigParser) EnhancedExactUnmarshal(output any) error {
oType := reflect.TypeOf(output)
if oType.Kind() != reflect.Pointer {
return errors.Errorf("supplied output argument must be a pointer to a struct but is not pointer")
}
eType := oType.Elem()
if eType.Kind() != reflect.Struct {
return errors.Errorf("supplied output argument must be a pointer to a struct, but it is pointer to something else")
}
baseKeys := c.config
leafKeys := getKeysRecursively("", c.getFromEnv, baseKeys, eType)
logger.Debugf("%+v", leafKeys)
config := &mapstructure.DecoderConfig{
ErrorUnused: true,
Metadata: nil,
Result: output,
WeaklyTypedInput: true,
DecodeHook: mapstructure.ComposeDecodeHookFunc(
bccspHook,
mapstructure.StringToTimeDurationHookFunc(),
customDecodeHook,
byteSizeDecodeHook,
stringFromFileDecodeHook,
pemBlocksFromFileDecodeHook,View on GitHub (pinned to 2736b63f8f)
Solutions
- Define a target struct matching your config keys and pass its pointer.
- If you need dynamic maps, use plain viper.Get/mapstructure decode instead of EnhancedExactUnmarshal.
- If using generics/any, assert the concrete struct pointer type before calling.
Example fix
// before
out := map[string]any{}
parser.EnhancedExactUnmarshal(&out)
// after
type MyConfig struct { Peer string }
out := MyConfig{}
parser.EnhancedExactUnmarshal(&out) Defensive patterns
Strategy: type-guard
Validate before calling
t := reflect.TypeOf(out)
if t == nil || t.Kind() != reflect.Pointer || t.Elem().Kind() != reflect.Struct {
return errors.New("output must be a pointer to a struct")
} Type guard
func isStructPointer(v any) bool {
t := reflect.TypeOf(v)
return t != nil && t.Kind() == reflect.Pointer && t.Elem().Kind() == reflect.Struct
} Try / catch
if !isStructPointer(&out) { /* restructure */ }
if err := parser.EnhancedExactUnmarshal(&out); err != nil {
return fmt.Errorf("config unmarshal failed: %w", err)
} Prevention
- Define a struct type that mirrors your config keys before unmarshaling
- Avoid unmarshaling into map[string]any with EnhancedExactUnmarshal; use plain viper instead
- Beware of generic wrappers that erase struct types with any
When it happens
Trigger: Calling parser.EnhancedExactUnmarshal(&someMap) or &someSlice; passing **struct double pointers may also fail the kind checks depending on reflection handling.
Common situations: Developers try to unmarshal into map[string]any to 'just get everything', but EnhancedExactUnmarshal deliberately targets structs; generic wrapper functions using any erase the struct type.
Related errors
- supplied output argument must be a pointer to a struct but i
- message of type %s unknown
- value '%s' overflows uint32
- Value of File: was nil
- must be pointer to struct, but got non-pointer %v
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3b003debff74d9b5.
Report an issue: GitHub.