Commit 6a1f56b
authored
fix: resolve disabled entities via entity_registry in helper deletion (homeassistant-ai#1119)
* fix: resolve disabled entities via entity_registry in helper deletion
Closes homeassistant-ai#1057. Disabled entities are removed from the state machine but
remain in the entity registry (`disabled_by != null`). The existing
state_check guard at the top of the registry-lookup loop hit `continue`
when state_check was None, skipping the registry lookup for all 3
attempts. The code then fell through to direct_id (often a no-op for
disabled helpers) and finally to the `already_deleted` short-circuit,
leaving the registry entry in place while the tool reported success.
Per option 3.1 from the issue thread (minimal blast radius): drop the
`continue` so the registry lookup runs every iteration. The retry/sleep
is preserved as the race-condition guard for entities that just
transitioned state.
Adds a unit test `test_simple_path_disabled_entity_resolves_via_registry`
that pins the registry-fallthrough path: state_check returns None,
registry returns a valid unique_id, and the standard websocket-delete
path runs (rather than misclassifying as already_deleted).
Local: 32/32 unit tests pass; ruff and mypy clean.
* fix: drop redundant state-check sleep on disabled-entity path
Per Gemini G2 review on PR homeassistant-ai#1119: with the `continue` removed in commit
69bb587, the state-check `asyncio.sleep` no longer functions as a
race-condition guard — the registry-fail block below already provides
retry-backoff. Keeping both produced a measurable but pointless
0.5s/attempt latency on the disabled-entity-deletion path:
- common case (registry has uid): pre-fix 1.5s + bug → 69bb587 0.5s + correct
→ this commit 0s + correct
- rare case (registry fails 3x): pre-fix 1.5s + already_deleted → 69bb587
3.0s + already_deleted → this commit 1.5s + already_deleted (parity)
The state-check itself stays as an informational debug log; only the
sleep is removed. Exception handling at L1000 is unchanged
(`HomeAssistantAPIError` only) — Gemini's suggested broader `except
Exception` was declined because it would swallow auth/connection
errors that the existing comment explicitly says must propagate.
Local: 32/32 unit tests pass; ruff and mypy clean.
* test(e2e): add disabled-entity regression test for homeassistant-ai#1057
End-to-end mirror of the unit test
`test_simple_path_disabled_entity_resolves_via_registry`. Creates an
`input_button` helper, disables its entity via
`ha_set_entity(enabled=False)`, deletes it via
`ha_delete_helpers_integrations`, and asserts the standard
`websocket_delete` path ran (rather than the `already_deleted`
short-circuit that masked the bug pre-fix).
Verifies registry entry actually goes away post-delete — pre-fix the
tool reported success while the registry entry stayed.
Closes the integration-level coverage gap noted in the IS comment.
* docs: tighten state-check comment per Gemini G3 review
* test(e2e): adjust post-delete error-code expectation
The new disabled-helper deletion test asserted that ha_get_entity
returns ENTITY_NOT_FOUND post-delete. The actual error code is
SERVICE_CALL_FAILED (with 'Entity not found' in the message) — the
HA-side error surfaces through the service-call layer rather than the
entity-not-found layer. Loosen the assertion to check the message
content and require success=False; the load-bearing claim is
'entity is gone, not still present', not the specific error code.
* docs: tighten test comment per G3 principle
Mirror the comment-verbosity reduction from 3f764ce to the test-side:
shrink the post-delete-verification comment from 6 lines to 2, keeping
the load-bearing 'why message-check, not code-check' rationale and
dropping verbose padding.1 parent 2213c89 commit 6a1f56b
3 files changed
Lines changed: 301 additions & 34 deletions
File tree
- src/ha_mcp/tools
- tests/src
- e2e/workflows/config
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
971 | 971 | | |
972 | 972 | | |
973 | 973 | | |
974 | | - | |
| 974 | + | |
| 975 | + | |
975 | 976 | | |
976 | 977 | | |
977 | 978 | | |
| |||
982 | 983 | | |
983 | 984 | | |
984 | 985 | | |
985 | | - | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
986 | 991 | | |
987 | 992 | | |
988 | 993 | | |
989 | | - | |
990 | | - | |
991 | | - | |
992 | | - | |
993 | | - | |
994 | | - | |
995 | | - | |
996 | | - | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
997 | 998 | | |
998 | 999 | | |
999 | 1000 | | |
| |||
1009 | 1010 | | |
1010 | 1011 | | |
1011 | 1012 | | |
1012 | | - | |
1013 | | - | |
| 1013 | + | |
| 1014 | + | |
1014 | 1015 | | |
1015 | 1016 | | |
1016 | 1017 | | |
| |||
1075 | 1076 | | |
1076 | 1077 | | |
1077 | 1078 | | |
1078 | | - | |
| 1079 | + | |
| 1080 | + | |
| 1081 | + | |
| 1082 | + | |
1079 | 1083 | | |
1080 | 1084 | | |
1081 | 1085 | | |
1082 | | - | |
1083 | | - | |
1084 | | - | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
| 1092 | + | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
| 1103 | + | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
| 1119 | + | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
1085 | 1154 | | |
1086 | | - | |
1087 | | - | |
1088 | | - | |
1089 | | - | |
1090 | | - | |
1091 | | - | |
1092 | | - | |
1093 | | - | |
1094 | | - | |
1095 | | - | |
1096 | | - | |
1097 | | - | |
1098 | | - | |
1099 | | - | |
1100 | | - | |
1101 | 1155 | | |
1102 | 1156 | | |
1103 | 1157 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
620 | 620 | | |
621 | 621 | | |
622 | 622 | | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
623 | 721 | | |
624 | 722 | | |
625 | 723 | | |
| |||
0 commit comments