AlexxIT/go2rtc · error
tlv8: not implemented:
Error message
tlv8: not implemented:
What it means
tlv8.Marshal only supports top-level values whose reflect kind is Slice or Struct (after dereferencing a pointer). Any other kind (map, string, int, bool, etc.) has no TLV8 encoding defined in this library, so it returns this error naming the unsupported kind. TLV8 encoding in HAP is defined for tagged struct/slice-of-struct values only.
Solutions
- Wrap the payload in a struct with `tlv8:"<tag>"` field tags and marshal that struct.
- Pass a slice of tagged structs (each element becomes a TLV8 record).
- Dereference or type-assert the value to a struct/slice before calling Marshal.
- Check the value's kind at runtime and reject unsupported types before calling Marshal.
Example fix
// before
data, err := tlv8.Marshal(map[string]string{"State": "1"}) // tlv8: not implemented: map
// after
type payload struct {
State byte `tlv8:"6"`
}
data, err := tlv8.Marshal(payload{State: 1}) Defensive patterns
Strategy: type-guard
Validate before calling
func marshalable(v any) bool {
k := reflect.ValueOf(v).Kind()
if k == reflect.Pointer { k = reflect.ValueOf(v).Elem().Kind() }
return k == reflect.Slice || k == reflect.Struct
}
// guard: if !marshalable(v) { return fmt.Errorf("tlv8 marshal needs struct or slice, got %T", v) } Type guard
func isStructOrSlice(v any) bool {
rv := reflect.ValueOf(v)
if rv.Kind() == reflect.Pointer { rv = rv.Elem() }
return rv.Kind() == reflect.Slice || rv.Kind() == reflect.Struct
} Try / catch
b, err := tlv8.Marshal(v)
if err != nil {
return fmt.Errorf("tlv8.Marshal %T: %w", v, err)
} Prevention
- Always marshal tagged structs (or slices of them), never maps or bare values.
- Add a unit test that marshals every payload type you use.
- Keep an `any`-typed value out of Marshal unless you know its concrete kind.
When it happens
Trigger: Calling tlv8.Marshal (directly or via MarshalBase64/MarshalReader, or indirectly from Dial/Pair/PairSetup/PairVerify) with a value whose dereferenced kind is not Slice or Struct, e.g. tlv8.Marshal(map[string]int{...}) or tlv8.Marshal("foo").
Common situations: Passing a JSON-decoded map[string]any instead of a typed struct; forgetting a pointer dereference layer such that kind stays Interface; marshalling a bare string/number payload; copying a struct into an interface used as `any` holding a non-struct type.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- tlv8: unsupported array:
- tlv8: value should be pointer:
- tlv8: unmarshal zero data
- tlv8: wrong size:
- tlv8: zero item
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/253b23a2ee60400a.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/hap/tlv8/tlv8.go:55
}
func Marshal(v any) ([]byte, error) {
value := reflect.ValueOf(v)
kind := value.Type().Kind()
if kind == reflect.Pointer {
value = value.Elem()
kind = value.Type().Kind()
}
switch kind {
case reflect.Slice:
return appendSlice(nil, value)
case reflect.Struct:
return appendStruct(nil, value)
}
return nil, errors.New("tlv8: not implemented: " + kind.String())
}
// separator the most confusing meaning in the documentation.
// It can have a value of 0x00 or 0xFF or even 0x05.
const separator = 0xFF
func appendSlice(b []byte, value reflect.Value) ([]byte, error) {
for i := 0; i < value.Len(); i++ {
if i > 0 {
b = append(b, separator, 0)
}
var err error
if b, err = appendStruct(b, value.Index(i)); err != nil {
return nil, err
}
}
return b, nil
}View on GitHub (pinned to c245815e75)