Suggest close matches for unknown YAML configuration keys (#182124)

This commit is contained in:
Franck Nijhof
2026-09-14 07:00:58 +02:00
committed by GitHub
parent c96751f20f
commit 720ead6325
2 changed files with 52 additions and 3 deletions
+6 -3
View File
@@ -479,10 +479,13 @@ def stringify_invalid(
message_prefix += f" at {_relpath(hass, annotation[0])}, line {annotation[1]}"
path = "->".join(str(m) for m in exc.path)
if exc.code == "extra_keys_not_allowed":
return (
f"{message_prefix}: '{exc.path[-1]}' is an invalid option for '{domain}', "
f"check: {path}{message_suffix}"
message = (
f"{message_prefix}: '{exc.path[-1]}' is an invalid option for '{domain}'"
)
if candidates := exc.context.get("candidates"):
options = " or ".join(f"'{candidate}'" for candidate in candidates)
message += f" (did you mean {options}?)"
return f"{message}, check: {path}{message_suffix}"
if exc.error_message == "required key not provided":
return (
f"{message_prefix}: required key '{exc.path[-1]}' not provided"
+46
View File
@@ -1481,6 +1481,52 @@ async def test_component_config_validation_error_with_docs(
assert error_records == snapshot
@pytest.mark.parametrize(
("key", "expected"),
[
pytest.param(
"command_topci",
"'command_topci' is an invalid option for 'mqtt' "
"(did you mean 'command_topic'?), check: command_topci",
id="one_candidate",
),
pytest.param(
"command_t",
"'command_t' is an invalid option for 'mqtt' "
"(did you mean 'command_topic' or 'command_template'?), check: command_t",
id="two_candidates",
),
pytest.param(
"totally_unrelated",
"'totally_unrelated' is an invalid option for 'mqtt', "
"check: totally_unrelated",
id="no_candidate",
),
],
)
async def test_stringify_invalid_suggests_close_keys(
hass: HomeAssistant, key: str, expected: str
) -> None:
"""Test an unknown option reports the close matches probatio found."""
schema = probatio.Schema(
{
probatio.Optional("command_topic"): str,
probatio.Optional("command_template"): str,
}
)
config = {key: "some-value"}
with pytest.raises(probatio.MultipleInvalid) as exc_info:
schema(config)
assert (
config_util.stringify_invalid(
hass, exc_info.value.errors[0], "mqtt", config, None, 500
)
== f"Invalid config for 'mqtt': {expected}"
)
@pytest.mark.parametrize(
"config_dir",
["packages", "packages_include_dir_named"],