home-assistant/core · error · InvalidConfigEntryID
Config entry {config_entry_id} not found
Error message
Config entry {config_entry_id} not found What it means
InvalidConfigEntryID raised by config_entry_id_to_source: hass.config_entries.async_get_entry(config_entry_id) returned nothing, so the passed id does not correspond to any existing config entry (deleted, never existed, or typo'd). The function exists to turn a Bluetooth config entry id into a scanner source address.
Source
Thrown at homeassistant/components/bluetooth/util.py:131
):
connectable_loaded_history[address] = service_info
return all_loaded_history, connectable_loaded_history
@callback
def adapter_title(adapter: str, details: AdapterDetails) -> str:
"""Return the adapter title."""
unique_name = adapter_unique_name(adapter, details[ADAPTER_ADDRESS])
model = details.get(ADAPTER_PRODUCT, "Unknown")
manufacturer = details[ADAPTER_MANUFACTURER] or "Unknown"
return f"{manufacturer} {model} ({unique_name})"
def config_entry_id_to_source(hass: HomeAssistant, config_entry_id: str) -> str:
"""Convert a config entry id to a source."""
if not (entry := hass.config_entries.async_get_entry(config_entry_id)):
raise InvalidConfigEntryID(f"Config entry {config_entry_id} not found")
source = entry.unique_id
assert source is not None
if not get_manager().async_scanner_by_source(source):
raise InvalidSource(f"Source {source} not found")
return source
View on GitHub (pinned to 58a3fdb3ea)
Solutions
- Re-fetch the current config entry id (Settings > Devices & Services, or config_entries API) and pass that
- If the entry was deleted intentionally, remove the automation/script/UI element that still stores the old id
- Catch InvalidConfigEntryID and re-enumerate entries instead of retrying the same id
Example fix
# before source = config_entry_id_to_source(hass, stale_entry_id) # after entry = hass.config_entries.async_entries(bluetooth.__dict__['DOMAIN'])[0] source = config_entry_id_to_source(hass, entry.entry_id)
Defensive patterns
Strategy: validation
Validate before calling
def config_entry_exists(hass, config_entry_id: str) -> bool:
return hass.config_entries.async_get_entry(config_entry_id) is not None Try / catch
from homeassistant.components.bluetooth.util import InvalidConfigEntryID
try:
source = config_entry_id_to_source(hass, entry_id)
except InvalidConfigEntryID:
entry_id = hass.config_entries.async_entries("bluetooth")[0].entry_id # re-resolve
source = config_entry_id_to_source(hass, entry_id) Prevention
- Resolve entry ids at call time, never cache them across reloads/deletes
- In UIs, re-fetch the entry list when a stored id fails validation
When it happens
Trigger: Calling config_entry_id_to_source (directly or via a websocket/API that accepts a config_entry_id) with an id from a stale UI session after the entry was removed, a truncated id, or a random string.
Common situations: Frontend dialog holding an entry id across a reload/delete; scripts or blueprints referencing an entry that was re-created with a new id; copy-paste of an id with missing characters.
Related errors
- device_not_found
- Credential is already linked to a user
- System generated users cannot disable multi-factor auth modu
- Invalid credentials: {ex}
- Unable to connect to Abode: {ex}
AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14).
Data as JSON: /api/errors/114fb37e6469fcbe.
Report an issue: GitHub.