{"record":{"id":"740495cc4fc668db","repo":"AlexxIT/go2rtc","slug":"tlv8-zero-item","errorCode":null,"errorMessage":"tlv8: zero item","messagePattern":"tlv8: zero item","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/hap/tlv8/tlv8.go","lineNumber":237,"sourceCode":"\t}\n\n\treturn errors.New(\"tlv8: not implemented: \" + kind.String())\n}\n\n// unmarshalTLV can return two types of errors:\n// - critical and then the value of []byte will be nil\n// - not critical and then []byte will contain the value\nfunc unmarshalTLV(b []byte, value reflect.Value) ([]byte, error) {\n\tif len(b) < 2 {\n\t\treturn nil, errors.New(\"tlv8: wrong size: \" + value.Type().Name())\n\t}\n\n\tt := b[0]\n\tl := int(b[1])\n\n\t// array item divider (t == 0x00 || t == 0xFF)\n\tif l == 0 {\n\t\treturn b[2:], errors.New(\"tlv8: zero item\")\n\t}\n\n\tvar v []byte\n\n\tfor {\n\t\tif len(b) < 2+l {\n\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])","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/hap/tlv8/tlv8.go#L219-L255","documentation":"A TLV8 record with length byte L == 0 carries no value; the library treats this as a non-critical condition: it skips the 2-byte header (returning b[2:], so decoding continues) but still reports \"tlv8: zero item\". Callers like unmarshalStruct ignore the error and keep looping; unmarshalSlice uses the non-nil remaining bytes to advance to the next array element. It typically signals a separator/empty record or a struct field encoded with length 0.","triggerScenarios":"Any Unmarshal call whose payload contains a record with L=0 — e.g. a field encoded as tag,0x00 with no value (often an empty struct tag written by appendValue as tag,0x00), or a 0xFF,0x00 array separator — decoded through unmarshalTLV from unmarshalSlice/unmarshalStruct.","commonSituations":"Empty optional fields in HAP pairing payloads (e.g. zero-length identifiers); payloads produced by other TLV8 implementations that encode empty values as L=0; separators between array items misread as zero-length records; decoding data from a non-Go peer with different empty-value conventions.","solutions":["No action needed if fields are intentionally empty: the library skips L=0 records and continues; treat this as informational.","If the missing value matters, validate after decoding that the expected struct fields are non-zero before using the result.","If you control the encoder, encode empty values with the correct tag/length rather than bare tag,0x00 records.","Confirm the payload source matches the expected TLV8 schema (tags and field order) — a zero item where data is expected usually means wrong payload type."],"exampleFix":"// before\ntlv8.Unmarshal(data, &resp) // assume all fields populated\nusePairing(resp.Identifier) // Identifier empty -> zero item was skipped\n\n// after\ntlv8.Unmarshal(data, &resp)\nif len(resp.Identifier) == 0 {\n    return errors.New(\"peer sent empty identifier (tlv8 zero item)\")\n}","handlingStrategy":"validation","validationCode":"// after decoding, verify required fields were populated\nif err := tlv8.Unmarshal(data, &resp); err != nil {\n    return err\n}\nif resp.Identifier == nil || len(resp.Identifier) == 0 {\n    return errors.New(\"required tlv8 field 1 (identifier) missing or empty\")\n}","typeGuard":null,"tryCatchPattern":"// zero item is non-critical: the library skips it, so validate results afterwards\nif err := tlv8.Unmarshal(data, &resp); err != nil {\n    return err\n}\nif reflect.ValueOf(resp).IsZero() {\n    return errors.New(\"tlv8 payload decoded to empty result (zero items only)\")\n}","preventionTips":["Treat L=0 records as 'field absent' and always validate required fields after Unmarshal.","When interoperating with other TLV8 implementations, agree on how empty values are encoded.","Distinguish array separators (0xFF,0x00) from genuine zero-length values when inspecting raw payloads.","Add unit tests with empty-field payloads so downstream code handles them explicitly."],"tags":["tlv8","empty-value","unmarshal","protocol","go"],"backgroundTag":"empty-required-field","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"}