home-assistant/core · info · AbortFlow

already_in_progress

Error message

already_in_progress

What it means

AbortFlow('already_in_progress') raised from the apple_tv config flow's _async_check_and_update_in_progress when another matching discovery flow (same host, source=zeroconf) is already active. HA's flow manager converts it into the standard 'already_in_progress' abort so the second discovery event attaches to the existing flow instead of creating a duplicate.

Source

Thrown at homeassistant/components/apple_tv/config_flow.py:291

        # window before triggering a scan of the device. This prevents
        # multiple scans of the device at the same time since each
        # apple_tv device has multiple services that are discovered by
        # zeroconf.
        #
        self._async_check_and_update_in_progress(host, unique_id)
        await asyncio.sleep(DISCOVERY_AGGREGATION_TIME)
        # Check again after sleeping in case another flow
        # has made progress while we yielded to the event loop
        self._async_check_and_update_in_progress(host, unique_id)
        # Host must only be set AFTER checking and updating in progress
        # flows or we will have a race condition where no flows move forward.
        self.host = host

    @callback
    def _async_check_and_update_in_progress(self, host: str, unique_id: str) -> None:
        """Check for in-progress flows and update them with identifiers if needed."""
        if self.hass.config_entries.flow.async_has_matching_flow(self):
            raise AbortFlow("already_in_progress")

    @override
    def is_matching(self, other_flow: Self) -> bool:
        """Return True if other_flow is matching this flow."""
        if (
            other_flow.context.get("source") != SOURCE_ZEROCONF
            or other_flow.host != self._host
        ):
            return False
        if self.unique_id is not None:
            # Add potentially new identifiers from this device to the existing flow
            other_flow.all_identifiers.add(self.unique_id)
        return True

    async def async_found_zeroconf_device(
        self, user_input: dict[str, str] | None = None
    ) -> ConfigFlowResult:
        """Handle device found after Zeroconf discovery."""

View on GitHub (pinned to 58a3fdb3ea)

Solutions

  1. No action needed in most cases: the abort means the existing flow will complete; wait for the config entry to appear
  2. If flows get stuck, reload the page/restart discovery by power cycling the device's network or restarting HA, then let a single flow finish
  3. Check for duplicate discovery sources (e.g. network with two mDNS reflectors) if this appears constantly
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: A zeroconf discovery event arrives for an Apple TV while a flow for the same host is already in progress; after the DISCOVERY_AGGREGATION_TIME sleep the flow re-checks and finds itself matched by async_has_matching_flow, which happens when multiple mDNS records for the device fire near-simultaneously.

Common situations: Apple TV advertising several service types (MAP, AirPlay, Companion) at once, each triggering discovery; device re-announcing after wake or IP change; two HA instances or duplicate discovery sources racing. Usually benign - the flows merge.

Related errors


AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14). Data as JSON: /api/errors/4ae786054c87bdbb. Report an issue: GitHub.