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

  1. Re-pair or power-cycle the accessory so it rebuilds and re-exposes its accessory database.
  2. Verify the target really is a HAP camera: check the mDNS entry id matches DeviceID before Dial.
  3. Call GetAccessories directly and inspect the raw response to see whether the device answers with an empty or malformed body.
  4. 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

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


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, err

View on GitHub (pinned to c245815e75)