AlexxIT/go2rtc · error
hap: GetAccessories zero answer
Error message
hap: GetAccessories zero answer
What it means
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.
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.
Example fix
// before: indexing without checking emptiness
acc, err := client.GetFirstAccessory()
// after: check the list yourself and handle the empty case
accs, err := client.GetAccessories()
if err != nil { return err }
if len(accs) == 0 {
return fmt.Errorf("device %s exposed no accessories; re-pair or reboot", client.DeviceID)
}
acc := accs[0] Defensive patterns
Strategy: fallback
Validate before calling
accs, err := client.GetAccessories()
if err != nil { return err }
if len(accs) == 0 { return errors.New("device exposed no accessories; reboot or re-pair") } Type guard
func hasAccessories(accs []*hap.Accessory) bool { return len(accs) > 0 } Try / catch
acc, err := client.GetFirstAccessory()
if err != nil {
if strings.Contains(err.Error(), "zero answer") {
// fallback: reboot/re-pair path, or retry after startup delay
time.Sleep(5 * time.Second)
acc, err = client.GetFirstAccessory()
}
if err != nil { return err }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- hap: no free streams
- hap: wrong http status:
- hap: PairVerify with unknown client_id:
- hap: wrong request: %#v
- hap: wrong response: %#v, on request: %#v
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/2252d12e68e27c23.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/hap/client.go:288
if err != nil {
return nil, err
}
var v JSONAccessories
if err = json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, err
}
return v.Value, nil
}
func (c *Client) GetFirstAccessory() (*Accessory, error) {
accs, err := c.GetAccessories()
if err != nil {
return nil, err
}
if len(accs) == 0 {
return nil, errors.New("hap: GetAccessories zero answer")
}
return accs[0], nil
}
func (c *Client) GetCharacters(query string) ([]JSONCharacter, error) {
res, err := c.Get(PathCharacteristics + "?id=" + query)
if err != nil {
return nil, err
}
data, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
var v JSONCharacters
if err = json.Unmarshal(data, &v); err != nil {
return nil, errView on GitHub (pinned to c245815e75)