Skip to content

Forwarded platform setup failures are silently discarded — entry reports LOADED with the platform missing #176652

Description

@honzup

The problem

Not a duplicate of #176593 - that issue covers the unload-side symptom (unloading a phantom platform raised ValueError and wedged the entry into FAILED_UNLOAD; fixed by #176594, which closes it). This issue tracks the setup-side root cause, which #176594 deliberately does not touch: platform setup failures being silently discarded during forwarded setup.

Follow-up from the review discussion on #176594 (see the question from @nick-tgcs there): that PR makes EntityComponent.async_unload_entry tolerant of a never-registered entry, which removes the worst symptom (a later unload wedging the entry into non-recoverable FAILED_UNLOAD, #176593). This issue tracks the root cause, which remains unaddressed:

When a config entry forwards platform setups, per-platform failures are discarded:

  • _async_forward_entry_setups_locked gathers the per-platform setup tasks and ignores their results (config_entries.py).
  • Inside the forwarded ConfigEntry.async_setup, a failed result for a forwarded domain deliberately changes no state: "Only store setup result as state if it was not forwarded" (config_entries.py).

The consequence: if one platform's async_setup_entry raises or returns False (transient cloud error during a reload, a bug in one platform, etc.), the owning entry still reports LOADED, while that platform's entities silently don't exist. The only trace is a single "Error setting up entry <title> for <platform>" log line. There is:

  • no entry-level state reflecting the partial failure,
  • no retry - the platform stays missing until the next full reload,
  • no repair issue or UI hint for the user, who sees a healthy-looking integration with entities quietly absent.

Design question rather than one-line fix - options that come to mind, each with trade-offs:

  1. Treat a failed forwarded platform as an entry setup failure (ConfigEntryState.SETUP_ERROR/SETUP_RETRY), so the whole entry retries - strictest, but a single flaky platform would then bounce an otherwise-working entry.
  2. Keep the entry loaded but schedule a retry of just the failed platform (analogous to async_config_entry_first_refresh semantics).
  3. Keep current behaviour but surface it: create a repair issue / persistent notification naming the failed platform, so the state is at least visible.

Historical impact of leaving this silent, prior to #176594: #166228 (tibber notify), #159949 (esphome assist_satellite), #90180 (tibber sensor) - in all three the invisible phantom platform later escalated into a restart-only outage at unload time.

What version of Home Assistant Core has the issue?

core-2026.6.4 (behaviour unchanged on current dev)

What was the last working version of Home Assistant Core?

Not a regression - long-standing behaviour of the forwarded-setup path.

What type of installation are you running?

Home Assistant OS

Integration causing the issue

Not integration-specific - homeassistant.config_entries forwarded platform setup. Observed via tibber (notify), previously esphome (assist_satellite).

Link to integration documentation on our website

n/a

Diagnostics information

No response

Example YAML snippet

Anything in the logs that might be useful for us?

ERROR (MainThread) [homeassistant.config_entries] Error setting up entry Tibber for notify

Additional information

Reproduction: patch any forwarded platform's async_setup_entry to raise once during entry setup - the entry reaches LOADED, the platform's entities are absent, and nothing but the single error line records it. Before #176594, step 2 was "reload the entry → ValueError: Config entry was never loaded!FAILED_UNLOAD"; with #176594 the unload now succeeds, but the silent partial-load state this issue describes is untouched.

Related: #176593 (the unload-side symptom, fixed by #176594), #151771 (no runtime escape from FAILED_UNLOAD).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions