{"record":{"id":"253b23a2ee60400a","repo":"AlexxIT/go2rtc","slug":"tlv8-not-implemented","errorCode":null,"errorMessage":"tlv8: not implemented: ","messagePattern":"tlv8: not implemented: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hap/tlv8/tlv8.go","lineNumber":55,"sourceCode":"}\n\nfunc Marshal(v any) ([]byte, error) {\n\tvalue := reflect.ValueOf(v)\n\tkind := value.Type().Kind()\n\n\tif kind == reflect.Pointer {\n\t\tvalue = value.Elem()\n\t\tkind = value.Type().Kind()\n\t}\n\n\tswitch kind {\n\tcase reflect.Slice:\n\t\treturn appendSlice(nil, value)\n\tcase reflect.Struct:\n\t\treturn appendStruct(nil, value)\n\t}\n\n\treturn nil, errors.New(\"tlv8: not implemented: \" + kind.String())\n}\n\n// separator the most confusing meaning in the documentation.\n// It can have a value of 0x00 or 0xFF or even 0x05.\nconst separator = 0xFF\n\nfunc appendSlice(b []byte, value reflect.Value) ([]byte, error) {\n\tfor i := 0; i < value.Len(); i++ {\n\t\tif i > 0 {\n\t\t\tb = append(b, separator, 0)\n\t\t}\n\t\tvar err error\n\t\tif b, err = appendStruct(b, value.Index(i)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn b, nil\n}","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/hap/tlv8/tlv8.go#L37-L73","documentation":"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.","triggerScenarios":"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\").","commonSituations":"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.","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."],"exampleFix":"// before\ndata, err := tlv8.Marshal(map[string]string{\"State\": \"1\"}) // tlv8: not implemented: map\n\n// after\ntype payload struct {\n    State byte `tlv8:\"6\"`\n}\ndata, err := tlv8.Marshal(payload{State: 1})","handlingStrategy":"type-guard","validationCode":"func marshalable(v any) bool {\n    k := reflect.ValueOf(v).Kind()\n    if k == reflect.Pointer { k = reflect.ValueOf(v).Elem().Kind() }\n    return k == reflect.Slice || k == reflect.Struct\n}\n// guard: if !marshalable(v) { return fmt.Errorf(\"tlv8 marshal needs struct or slice, got %T\", v) }","typeGuard":"func isStructOrSlice(v any) bool {\n    rv := reflect.ValueOf(v)\n    if rv.Kind() == reflect.Pointer { rv = rv.Elem() }\n    return rv.Kind() == reflect.Slice || rv.Kind() == reflect.Struct\n}","tryCatchPattern":"b, err := tlv8.Marshal(v)\nif err != nil {\n    return fmt.Errorf(\"tlv8.Marshal %T: %w\", v, err)\n}","preventionTips":["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."],"tags":["tlv8","marshal","reflection","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}