{"record":{"id":"b7cc7e32664c655c","repo":"AlexxIT/go2rtc","slug":"tlv8-can-t-find-t-d-l-d-v-x-for-s","errorCode":null,"errorMessage":"tlv8: can't find T=%d,L=%d,V=%x for: %s","messagePattern":"tlv8: can't find T=(.+?),L=(.+?),V=%x for: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hap/tlv8/tlv8.go","lineNumber":262,"sourceCode":"\t\t\treturn nil, errors.New(\"tlv8: wrong size: \" + value.Type().Name())\n\t\t}\n\n\t\tv = append(v, b[2:2+l]...)\n\t\tb = b[2+l:]\n\n\t\t// if size == 255 and same tag - continue read big payload\n\t\tif l < 255 || len(b) < 2 || b[0] != t {\n\t\t\tbreak\n\t\t}\n\n\t\tl = int(b[1])\n\t}\n\n\ttag := strconv.Itoa(int(t))\n\n\tvalueField, ok := getStructField(value, tag)\n\tif !ok {\n\t\treturn b, fmt.Errorf(\"tlv8: can't find T=%d,L=%d,V=%x for: %s\", t, l, v, value.Type().Name())\n\t}\n\n\tif err := unmarshalValue(v, valueField); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn b, nil\n}\n\nfunc unmarshalSlice(b []byte, value reflect.Value) error {\n\tvalueIndex := value.Index(growSlice(value))\n\tfor len(b) > 0 {\n\t\tvar err error\n\t\tif b, err = unmarshalTLV(b, valueIndex); err != nil {\n\t\t\tif b != nil {\n\t\t\t\tvalueIndex = value.Index(growSlice(value))\n\t\t\t\tcontinue\n\t\t\t}","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/hap/tlv8/tlv8.go#L244-L280","documentation":"tlv8.unmarshalTLV encountered a TLV record whose Tag has no corresponding struct field (fields are matched by decimal tag name, e.g. `\"1\"`). The record's T, L and hex V are printed along with the target struct name. This happens when decoding TLV8 data containing tags the target struct does not model.","triggerScenarios":"Unmarshalling a TLV8 blob (e.g. a HAP pairing message) whose tag set includes values not present as fields in the destination struct — typically a device using newer/extra tags than the struct supports.","commonSituations":"Accessories implementing newer HAP protocol extensions; mismatched struct definitions after a library upgrade; decoding vendor-specific TLVs into a generic struct.","solutions":["Add a field named after the missing tag (string name of the tag number) to the target struct, or a catch-all map field if supported.","Upgrade the tlv8/hap library so its structs cover the new tags.","Dump the failing T,L,V from the error and check which HAP spec tag it corresponds to.","If the tag is ignorable, pre-filter it from the TLV slice before unmarshalling."],"exampleFix":"// before\ntype pairVerifyResponse struct {\n    \"1\" []byte\n    \"3\" []byte\n}\n// after (device also sends tag 2)\ntype pairVerifyResponse struct {\n    \"1\" []byte\n    \"2\" []byte\n    \"3\" []byte\n}","handlingStrategy":"try-catch","validationCode":"// pre-scan TLV records and drop unknown tags before unmarshalling\nfunc knownOnly(recs []tlv8.Record, known map[byte]bool) []tlv8.Record { ... }","typeGuard":null,"tryCatchPattern":"err := tlv8.Unmarshal(data, &msg)\nif err != nil {\n    var tlvErr error\n    if errors.As(err, &tlvErr) && strings.Contains(err.Error(), \"can't find T=\") {\n        log.Printf(\"unknown TLV tag from device: %v\", err)\n    }\n    return err\n}","preventionTips":["Keep tlv8/hap structs in sync with the devices you deploy","Prefer decoding into a map/tlv8.Records first to inspect unknown tags","Log T/L/V from the error message to map against the HAP spec","Update the library when accessories get firmware upgrades adding new tags"],"tags":["go","tlv8","unmarshal","homekit"],"backgroundTag":"schema-validation-failed","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}