diff --git a/esphome/writer.py b/esphome/writer.py index 6f061c53de..fbe36699e9 100644 --- a/esphome/writer.py +++ b/esphome/writer.py @@ -337,14 +337,14 @@ def copy_src_tree(): else: try: existing = json.loads(build_info_json_path.read_text(encoding="utf-8")) - if ( + if not isinstance(existing, dict) or ( existing.get("config_hash") != config_hash or existing.get("esphome_version") != __version__ ): + # Valid JSON that is not an object (truncated or + # hand-edited) is stale like every other damage case sources_changed = True - except (json.JSONDecodeError, AttributeError, KeyError, OSError): - # AttributeError: valid JSON that is not an object (truncated - # or hand-edited) has no .get; treat it as stale like the rest + except (json.JSONDecodeError, OSError): sources_changed = True # Write build_info header and JSON metadata diff --git a/tests/unit_tests/test_writer.py b/tests/unit_tests/test_writer.py index b0de99e039..37d999a816 100644 --- a/tests/unit_tests/test_writer.py +++ b/tests/unit_tests/test_writer.py @@ -2232,7 +2232,7 @@ def test_copy_src_tree_handles_non_dict_build_info_json( build_path = tmp_path / "build" build_path.mkdir() - # Create invalid build_info.json + # Valid JSON that is not an object: no .get, must read as stale build_info_json_path = build_path / "build_info.json" build_info_json_path.write_text("[]")