[core] Fix area/device hash collision validation not running (#15259)

This commit is contained in:
Jonathan Swoboda
2026-03-27 22:22:24 -04:00
committed by GitHub
parent 47774fb644
commit b6abfec82e
5 changed files with 64 additions and 9 deletions
+18
View File
@@ -958,6 +958,23 @@ class FinalValidateValidationStep(ConfigValidationStep):
fv.full_config.reset(token)
class CoreFinalValidateStep(ConfigValidationStep):
"""Run final validation on core esphome config (area/device hash collisions)."""
# Same priority as component final validate steps
priority = -20.0
def run(self, result: Config) -> None:
if result.errors:
return
token = fv.full_config.set(result)
with result.catch_error([CONF_ESPHOME]):
if CONF_ESPHOME in result:
core_config.validate_ids_and_references(result[CONF_ESPHOME])
fv.full_config.reset(token)
class PinUseValidationCheck(ConfigValidationStep):
"""Check for pin reuse"""
@@ -1085,6 +1102,7 @@ def validate_config(
for domain, conf in config.items():
result.add_validation_step(LoadValidationStep(domain, conf))
result.add_validation_step(IDPassValidationStep())
result.add_validation_step(CoreFinalValidateStep())
result.add_validation_step(PinUseValidationCheck())
result.add_validation_step(RemoveReferenceValidationStep())
+6 -9
View File
@@ -156,22 +156,22 @@ def validate_ids_and_references(config: ConfigType) -> ConfigType:
hash_dict[hash_val] = id_obj.id
# Collect all areas
all_areas: list[dict[str, str | core.ID]] = []
all_areas: list[tuple[dict[str, str | core.ID], str]] = []
if CONF_AREA in config:
all_areas.append(config[CONF_AREA])
all_areas.extend(config[CONF_AREAS])
all_areas.append((config[CONF_AREA], CONF_AREA))
all_areas.extend((area, CONF_AREAS) for area in config.get(CONF_AREAS, []))
# Validate area hash collisions and collect IDs
area_hashes: dict[int, str] = {}
area_ids: set[str] = set()
for area in all_areas:
for area, key in all_areas:
area_id: core.ID = area[CONF_ID]
check_hash_collision(area_id, area_hashes, "Area", [CONF_AREAS, area_id.id])
check_hash_collision(area_id, area_hashes, "Area", [key, area_id.id])
area_ids.add(area_id.id)
# Validate device hash collisions and area references
device_hashes: dict[int, str] = {}
for device in config[CONF_DEVICES]:
for device in config.get(CONF_DEVICES, []):
device_id: core.ID = device[CONF_ID]
check_hash_collision(
device_id, device_hashes, "Device", [CONF_DEVICES, device_id.id]
@@ -329,9 +329,6 @@ CONFIG_SCHEMA = cv.All(
)
FINAL_VALIDATE_SCHEMA = cv.All(validate_ids_and_references)
PRELOAD_CONFIG_SCHEMA = cv.Schema(
{
cv.Required(CONF_NAME): cv.valid_name,