Skip to content

Fix unload KeyError for failed device setup#5381

Merged
make-all merged 2 commits into
make-all:mainfrom
geekypilot:fix/async-delete-keyerror
Jun 21, 2026
Merged

Fix unload KeyError for failed device setup#5381
make-all merged 2 commits into
make-all:mainfrom
geekypilot:fix/async-delete-keyerror

Conversation

@geekypilot

@geekypilot geekypilot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

This fixes an unload crash that can happen when a Tuya device is offline during Home Assistant startup. In that state Home Assistant may leave the config entry in setup_retry, while tuya-local never finishes creating the usual cached device data under hass.data.

Later, when Home Assistant reloads, updates, or shuts down that entry, the integration still runs its unload path. Before this change, that path assumed the cached device entry and all of its internal keys existed, so it could raise a KeyError instead of completing the unload.

This PR makes that cleanup path defensive for setup-failed entries:

  • async_unload_entry now tolerates a missing hass.data[DOMAIN][device_id] entry and treats it as already unloaded.
  • async_delete_device now tolerates missing or partially initialized cached handles.
  • Device cleanup still awaits async_stop() before removing the cached device object, so a stop failure does not silently discard the device reference first.

The intent is to keep normal unload behavior unchanged for devices that completed setup, while preventing failed setup or setup_retry entries from crashing later reload/update/shutdown flows.

Reported traceback

Traceback (most recent call last):
  File "/config/custom_components/tuya_local/__init__.py", line 1001, in async_update_entry
    await async_unload_entry(hass, entry)
  File "/config/custom_components/tuya_local/__init__.py", line 993, in async_unload_entry
    await async_delete_device(hass, config)
  File "/config/custom_components/tuya_local/device.py", line 822, in async_delete_device
    del hass.data[DOMAIN][device_id]["device"]
KeyError: '<device_id>'

Device context

Scope notes

This PR is intentionally narrow. It addresses unload cleanup for setup-failed or partially initialized entries, but does not try to redesign broader cache recovery behavior. In particular, it does not add new handling for unrelated cases where platform entities were already forwarded and the device cache is later externally corrupted.

Testing

  • uv run pytest tests/test_config_flow.py::test_async_unload_entry_ignores_missing_device_data -q
  • uv run pytest tests/test_device.py::test_delete_keeps_device_entry_when_stop_fails -q
  • uv run pytest tests/test_device.py tests/test_config_flow.py -q
  • uv run pytest
  • uv run ruff check .
  • uv run ruff check --select I .
  • uv run ruff format --check .
  • uv run yamllint custom_components/tuya_local/devices

@github-project-automation github-project-automation Bot moved this to 👀 In review in Tuya Local Jun 20, 2026
@geekypilot
geekypilot marked this pull request as draft June 20, 2026 20:19
@geekypilot
geekypilot force-pushed the fix/async-delete-keyerror branch from 0732168 to ba20064 Compare June 20, 2026 20:30
@geekypilot
geekypilot marked this pull request as ready for review June 20, 2026 20:59
Comment thread custom_components/tuya_local/device.py
@make-all
make-all merged commit f99acd4 into make-all:main Jun 21, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from 👀 In review to ✅ Done in Tuya Local Jun 21, 2026
make-all added a commit that referenced this pull request Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants