OpenNHP/opennhp · error
data must be a pointer
Error message
data must be a pointer
What it means
toStructure is the file-to-struct deserialization entry point and requires its data argument to be a pointer, because unmarshal writes into the destination via reflection and must be able to address it. Passing a non-pointer makes this impossible, so the function fails fast with this error before any reading occurs.
Solutions
- Pass a pointer: toStructure(f, &myStruct).
- If you have an `any`, assert it holds a non-nil pointer before calling.
- Fix wrapper functions to require pointer parameters in their signatures.
- Document the pointer requirement in the wrapper's API to catch this at the call site.
Example fix
// before var hdr Header toStructure(f, hdr) // "data must be a pointer" // after var hdr Header err := toStructure(f, &hdr)
Defensive patterns
Strategy: type-guard
Validate before calling
func ensurePtr(v any) bool { return reflect.ValueOf(v).Kind() == reflect.Pointer } Type guard
if v := reflect.ValueOf(data); v.Kind() != reflect.Pointer || v.IsNil() {
return errors.New("toStructure requires a non-nil pointer")
} Try / catch
if err := toStructure(f, data); err != nil {
if strings.Contains(err.Error(), "data must be a pointer") {
return fmt.Errorf("call toStructure(f, &value), not toStructure(f, value)")
}
return err
} Prevention
- Habitually pass &struct to deserialization APIs
- Type wrapper functions as *T instead of any where possible
- Lint for toStructure calls whose argument is not address-of
When it happens
Trigger: Calling toStructure(f, someStruct) with a struct value instead of &someStruct; passing a non-pointer map/slice value; wrapper functions that accept `any` and forward a value instead of a pointer.
Common situations: Forgetting the & when passing a local struct; helper wrappers that accept `any` and forward without dereferencing; porting code from JSON APIs where non-pointer targets are sometimes allowed.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- data must be a struct
- unsupported field type
- unsupported field type
- unsupported element type
- unknown remote provider
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/922a38e0ea1c1dfc.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/ztdo/ztdo.go:628
}
}
return nil
}
// toBuffer provides unified way to serialize a Go struct into bytes buffer
func toBuffer(data any) *bytes.Buffer {
buf := bytes.NewBuffer(nil)
_ = marshal(buf, data)
return buf
}
// toStructure provides unified way to deserialize bytes from a file into a Go struct
func toStructure(f *os.File, data any) error {
lengthMap = make(map[string]uint32)
rValues := reflect.ValueOf(data)
if rValues.Kind() != reflect.Pointer {
return fmt.Errorf("data must be a pointer")
}
return unmarshal(f, data)
}
// setBytes provides unified way to set bytes to a slice or array
func setBytes(rvalue reflect.Value, dst []byte) {
if rvalue.Kind() == reflect.Slice {
rvalue.SetBytes(dst)
} else if rvalue.Kind() == reflect.Array {
len := rvalue.Len()
elType := rvalue.Type().Elem()
arrayType := reflect.ArrayOf(len, elType)
newArray := reflect.New(arrayType).Elem()
for i := range len {
newArray.Index(i).SetUint(uint64(dst[i]))
}View on GitHub (pinned to 6e04ca5ff0)