AlexxIT/go2rtc · error
tlv8: value should be pointer:
Error message
tlv8: value should be pointer:
What it means
tlv8.Unmarshal requires its output parameter `v` to be a pointer so it can write decoded fields into the caller's value via reflection. When `v` is passed by value (e.g. a struct or map, not `&struct`), reflect.ValueOf(v).Kind() is not reflect.Pointer and this error is returned before any decoding happens. The kind that was actually received is appended to the message to help identify the mistake.
Solutions
- Pass a pointer to the destination: tlv8.Unmarshal(data, &out) instead of tlv8.Unmarshal(data, out).
- If the value is held in an interface variable, store a pointer in it: var out any = &MyStruct{} before calling Unmarshal.
- If you only have a reflect.Value, verify rv.Kind() == reflect.Pointer && !rv.IsNil() before calling Unmarshal.
- Check wrapper call sites (Dial, Pair, PairSetup, PairVerify, UnmarshalBase64, UnmarshalReader) and confirm the out argument you supply to them is addressable.
Example fix
// before var resp pairVerifyResponse tlv8.Unmarshal(data, resp) // after var resp pairVerifyResponse tlv8.Unmarshal(data, &resp)
Defensive patterns
Strategy: type-guard
Validate before calling
// before calling
data, err := base64.StdEncoding.DecodeString(in)
if err != nil || len(data) == 0 {
return err
}
// ensure out is a non-nil pointer to struct/slice
rv := reflect.ValueOf(out)
if rv.Kind() != reflect.Pointer || rv.IsNil() {
return errors.New("out must be a non-nil pointer")
} Type guard
func isDecodableTarget(v any) bool {
rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Pointer || rv.IsNil() {
return false
}
k := rv.Elem().Kind()
return k == reflect.Struct || k == reflect.Slice
} Try / catch
// Go: handle the returned error, there is no panic
if err := tlv8.UnmarshalBase64(in, &out); err != nil {
if strings.HasPrefix(err.Error(), "tlv8: value should be pointer") {
return fmt.Errorf("bad unmarshal target: %w", err)
}
return err
} Prevention
- Always declare the destination variable and pass &var to Unmarshal/UnmarshalBase64/UnmarshalReader.
- Add a small wrapper in your codebase that type-asserts pointer targets before delegating to tlv8.
- Watch for interface-typed parameters: store pointers inside interface values, not values.
- Cover each unmarshal call site with a unit test so a dropped `&` fails immediately.
When it happens
Trigger: Calling tlv8.Unmarshal(data, out), tlv8.UnmarshalBase64(in, out), or tlv8.UnmarshalReader(r, n, out) — and transitively the HAP client methods Dial, Pair, PairSetup, PairVerify — with a non-pointer `out` argument, such as Unmarshal(data, structValue) instead of Unmarshal(data, &structValue).
Common situations: Declaring the destination struct but forgetting the `&` when calling Unmarshal/UnmarshalBase64; passing an interface variable that wraps a non-pointer; copying a helper that accepted **T and calling it with T; intermediate variables like `var out MyStruct` passed directly in multi-return calls.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- tlv8: wrong size:
- tlv8: zero item
- tlv8: can't find T= ,L= ,V= for
- tlv8: not implemented:
- tlv8: unmarshal zero data
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/68b19886acece36e.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/hap/tlv8/tlv8.go:203
data, err = io.ReadAll(r)
}
if err != nil {
return err
}
return Unmarshal(data, v)
}
func Unmarshal(data []byte, v any) error {
if len(data) == 0 {
return errors.New("tlv8: unmarshal zero data")
}
value := reflect.ValueOf(v)
kind := value.Kind()
if kind != reflect.Pointer {
return errors.New("tlv8: value should be pointer: " + kind.String())
}
value = value.Elem()
kind = value.Kind()
if kind == reflect.Interface {
value = value.Elem()
kind = value.Kind()
}
switch kind {
case reflect.Slice:
return unmarshalSlice(data, value)
case reflect.Struct:
return unmarshalStruct(data, value)
}
return errors.New("tlv8: not implemented: " + kind.String())View on GitHub (pinned to c245815e75)