The problem
OAuth flows initiated via homeassistant/components/cloud/account_link.py (i.e. any integration whose "Home Assistant Cloud" implementation is provided by Nabu Casa's account-link.nabucasa.com relay) silently fail to complete setup. The OAuth tokens are received from Nabu Casa successfully — visible in the log as hass_nabucasa.account_link DEBUG: Received tokens for <service> — but the config entry is never created and no error is logged.
The flow becomes invisible to config_entries/flow/progress (which filters out source=SOURCE_USER) but still holds the unique_id, so subsequent attempts abort with already_in_progress. Only a Home Assistant restart clears it, and the tokens are lost, so OAuth must be redone from scratch.
Root cause: After tokens arrive, account_link.py::await_tokens() calls flow.async_configure(flow_id, tokens). AbstractOAuth2FlowHandler.async_step_auth returns async_external_step_done(next_step_id="creation"). But data_entry_flow.py::FlowManager.async_configure's while-loop only auto-progresses from SHOW_PROGRESS_DONE, not EXTERNAL_STEP_DONE. In the local-redirect OAuth path this works because the frontend WebSocket subscriber sees the state change and calls configure() to advance. In the Nabu Casa cloud path the browser has navigated away to account-link.nabucasa.com/authorize_callback for the OAuth roundtrip — its HA WebSocket subscription is dead when the tokens arrive minutes later, so nothing triggers async_step_creation. The flow stalls indefinitely at EXTERNAL_STEP_DONE / step_id="creation".
Reproduction:
- HA with Nabu Casa cloud signed in (free account is enough — no paid subscription required).
- Settings → Devices & Services → Add Integration → YoLink (or any account_link-based integration).
- Pick "Home Assistant Cloud" implementation. HA tab navigates to the provider's OAuth (popup blocked by default in Chrome → same-tab navigation).
- Complete OAuth. Browser lands on Nabu Casa's
authorize_callback showing "Done!".
- Return to HA. Expected: YoLink integration card appears. Actual: No card. Retry gives "Configuration flow is already in progress".
Suggested fixes (either would work):
- In
homeassistant/components/cloud/account_link.py::CloudOAuth2Implementation.async_generate_authorize_url's await_tokens(): after await self.hass.config_entries.flow.async_configure(flow_id=flow_id, user_input=tokens), add a second await self.hass.config_entries.flow.async_configure(flow_id=flow_id) (no user_input) to advance past EXTERNAL_STEP_DONE.
- In
homeassistant/data_entry_flow.py::FlowManager.async_configure: extend the while-loop condition to also auto-progress from FlowResultType.EXTERNAL_STEP_DONE, symmetric with existing SHOW_PROGRESS_DONE handling.
Workaround used to unblock setup: A one-file custom_component exposing a service that iterates hass.config_entries.flow.async_progress() for the affected handler and calls hass.config_entries.flow.async_configure(flow_id) (with no user_input). This advances the stuck flow past EXTERNAL_STEP_DONE and async_step_creation runs normally, creating the config entry.
What version of Home Assistant Core has the issue?
core-2026.9.3
What was the last working version of Home Assistant Core?
No response
What type of installation are you running?
Home Assistant OS
Integration causing the issue
Home Assistant Cloud
Link to integration documentation on our website
https://www.home-assistant.io/integrations/cloud/
Diagnostics information
No response
Example YAML snippet
Anything in the logs that might be useful for us?
2026-09-23 14:09:30.469 DEBUG [hass_nabucasa.account_link] Opening connection for yolink
2026-09-23 14:09:36.987 DEBUG [hass_nabucasa.account_link] Received tokens for yolink
Zero further activity. In particular, `homeassistant.helpers.config_entry_oauth2_flow`'s `Creating config entry from external data` DEBUG line at the top of `async_step_creation` never fires, and no exception, warning, or error is emitted. The flow is left in `_progress` at `cur_step.type=EXTERNAL_STEP_DONE, step_id="creation"`.
Debug logging enabled for: `hass_nabucasa`, `hass_nabucasa.account_link`, `homeassistant.components.cloud`, `homeassistant.components.yolink`, `homeassistant.helpers.config_entry_oauth2_flow`, `homeassistant.data_entry_flow`, `homeassistant.config_entries`.
Additional information
Verified via source read on tag 2026.9.3 that both branches identified in "Suggested fixes" would resolve this. Popup handling doesn't fix the underlying bug — even with popups allowed, Chrome sometimes falls back to same-tab navigation for window.open calls without a user gesture, killing the WebSocket subscription. This is a design bug in the cloud-relay OAuth flow, not a browser issue.
The problem
OAuth flows initiated via
homeassistant/components/cloud/account_link.py(i.e. any integration whose "Home Assistant Cloud" implementation is provided by Nabu Casa'saccount-link.nabucasa.comrelay) silently fail to complete setup. The OAuth tokens are received from Nabu Casa successfully — visible in the log ashass_nabucasa.account_linkDEBUG:Received tokens for <service>— but the config entry is never created and no error is logged.The flow becomes invisible to
config_entries/flow/progress(which filters outsource=SOURCE_USER) but still holds the unique_id, so subsequent attempts abort withalready_in_progress. Only a Home Assistant restart clears it, and the tokens are lost, so OAuth must be redone from scratch.Root cause: After tokens arrive,
account_link.py::await_tokens()callsflow.async_configure(flow_id, tokens).AbstractOAuth2FlowHandler.async_step_authreturnsasync_external_step_done(next_step_id="creation"). Butdata_entry_flow.py::FlowManager.async_configure's while-loop only auto-progresses fromSHOW_PROGRESS_DONE, notEXTERNAL_STEP_DONE. In the local-redirect OAuth path this works because the frontend WebSocket subscriber sees the state change and callsconfigure()to advance. In the Nabu Casa cloud path the browser has navigated away toaccount-link.nabucasa.com/authorize_callbackfor the OAuth roundtrip — its HA WebSocket subscription is dead when the tokens arrive minutes later, so nothing triggersasync_step_creation. The flow stalls indefinitely atEXTERNAL_STEP_DONE / step_id="creation".Reproduction:
authorize_callbackshowing "Done!".Suggested fixes (either would work):
homeassistant/components/cloud/account_link.py::CloudOAuth2Implementation.async_generate_authorize_url'sawait_tokens(): afterawait self.hass.config_entries.flow.async_configure(flow_id=flow_id, user_input=tokens), add a secondawait self.hass.config_entries.flow.async_configure(flow_id=flow_id)(no user_input) to advance pastEXTERNAL_STEP_DONE.homeassistant/data_entry_flow.py::FlowManager.async_configure: extend the while-loop condition to also auto-progress fromFlowResultType.EXTERNAL_STEP_DONE, symmetric with existingSHOW_PROGRESS_DONEhandling.Workaround used to unblock setup: A one-file custom_component exposing a service that iterates
hass.config_entries.flow.async_progress()for the affected handler and callshass.config_entries.flow.async_configure(flow_id)(with no user_input). This advances the stuck flow pastEXTERNAL_STEP_DONEandasync_step_creationruns normally, creating the config entry.What version of Home Assistant Core has the issue?
core-2026.9.3
What was the last working version of Home Assistant Core?
No response
What type of installation are you running?
Home Assistant OS
Integration causing the issue
Home Assistant Cloud
Link to integration documentation on our website
https://www.home-assistant.io/integrations/cloud/
Diagnostics information
No response
Example YAML snippet
Anything in the logs that might be useful for us?
Additional information
Verified via source read on tag
2026.9.3that both branches identified in "Suggested fixes" would resolve this. Popup handling doesn't fix the underlying bug — even with popups allowed, Chrome sometimes falls back to same-tab navigation forwindow.opencalls without a user gesture, killing the WebSocket subscription. This is a design bug in the cloud-relay OAuth flow, not a browser issue.