{"record":{"id":"2252d12e68e27c23","repo":"AlexxIT/go2rtc","slug":"hap-getaccessories-zero-answer","errorCode":null,"errorMessage":"hap: GetAccessories zero answer","messagePattern":"hap: GetAccessories zero answer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hap/client.go","lineNumber":288,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar v JSONAccessories\n\tif err = json.NewDecoder(res.Body).Decode(&v); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn v.Value, nil\n}\n\nfunc (c *Client) GetFirstAccessory() (*Accessory, error) {\n\taccs, err := c.GetAccessories()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(accs) == 0 {\n\t\treturn nil, errors.New(\"hap: GetAccessories zero answer\")\n\t}\n\treturn accs[0], nil\n}\n\nfunc (c *Client) GetCharacters(query string) ([]JSONCharacter, error) {\n\tres, err := c.Get(PathCharacteristics + \"?id=\" + query)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdata, err := io.ReadAll(res.Body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar v JSONCharacters\n\tif err = json.Unmarshal(data, &v); err != nil {\n\t\treturn nil, err","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/hap/client.go#L270-L306","documentation":"GetFirstAccessory fetches the accessory list via GetAccessories and errors when the device answers successfully but returns an empty list. The library requires at least one accessory (cameras expose themselves as one), so an empty answer indicates the device did not expose its accessory table.","triggerScenarios":"Calling GetFirstAccessory on a device that answered the HTTP request but has no accessories registered (e.g. wrong /accessories endpoint behavior after firmware update, or the device is not actually a HAP accessory); the device is paired but its accessory database is empty or unreachable state.","commonSituations":"Firmware update resetting the accessory table; querying a device that shares the IP but is not the camera; device in a partially-initialized state right after reboot; stale mDNS entry pointing to a retired unit.","solutions":["Re-pair or power-cycle the accessory so it rebuilds and re-exposes its accessory database.","Verify the target really is a HAP camera: check the mDNS entry id matches DeviceID before Dial.","Call GetAccessories directly and inspect the raw response to see whether the device answers with an empty or malformed body.","Retry after the device finishes booting; accessories may be empty briefly during startup."],"exampleFix":"// before: indexing without checking emptiness\nacc, err := client.GetFirstAccessory()\n// after: check the list yourself and handle the empty case\naccs, err := client.GetAccessories()\nif err != nil { return err }\nif len(accs) == 0 {\n    return fmt.Errorf(\"device %s exposed no accessories; re-pair or reboot\", client.DeviceID)\n}\nacc := accs[0]","handlingStrategy":"fallback","validationCode":"accs, err := client.GetAccessories()\nif err != nil { return err }\nif len(accs) == 0 { return errors.New(\"device exposed no accessories; reboot or re-pair\") }","typeGuard":"func hasAccessories(accs []*hap.Accessory) bool { return len(accs) > 0 }","tryCatchPattern":"acc, err := client.GetFirstAccessory()\nif err != nil {\n    if strings.Contains(err.Error(), \"zero answer\") {\n        // fallback: reboot/re-pair path, or retry after startup delay\n        time.Sleep(5 * time.Second)\n        acc, err = client.GetFirstAccessory()\n    }\n    if err != nil { return err }\n}","preventionTips":["Retry with a delay after accessory boot; the table can be briefly empty.","Verify the device identity via mDNS before Dial to avoid querying a non-camera host.","Re-pair after firmware updates that reset the accessory database."],"tags":["hap","accessories","empty-response","homekit"],"backgroundTag":"empty-result-set","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"}