From dd91039ff1e6bae2070c671fe20c7f454f8dbce1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 15:43:16 -1000 Subject: [PATCH 1/4] Bump github/codeql-action from 4.31.11 to 4.32.0 (#13559) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 15edd8421a..be761cee3d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -58,7 +58,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 + uses: github/codeql-action/init@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -86,6 +86,6 @@ jobs: exit 1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 + uses: github/codeql-action/analyze@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 with: category: "/language:${{matrix.language}}" From 65dc1825267ca18be7eb92a778ec9803a61ecc1d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 15:43:27 -1000 Subject: [PATCH 2/4] Bump setuptools from 80.10.1 to 80.10.2 (#13558) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3ce2e6ebec..1bd43ea2f1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools==80.10.1", "wheel>=0.43,<0.47"] +requires = ["setuptools==80.10.2", "wheel>=0.43,<0.47"] build-backend = "setuptools.build_meta" [project] From 27a212c14da264f53070aadea3d0ce8e97aa0aaf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 15:43:40 -1000 Subject: [PATCH 3/4] Bump aioesphomeapi from 43.13.0 to 43.14.0 (#13557) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a707fda059..821324262b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20260110.0 -aioesphomeapi==43.13.0 +aioesphomeapi==43.14.0 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.19.1 # dashboard_import From 11783e9060b688da233a5715d5b0b93e8867cad0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 26 Jan 2026 16:16:06 -1000 Subject: [PATCH 4/4] [ota] Improve error message when device closes connection without responding --- esphome/espota2.py | 6 ++++++ tests/unit_tests/test_espota2.py | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/esphome/espota2.py b/esphome/espota2.py index 95dd602ad2..2d90251b38 100644 --- a/esphome/espota2.py +++ b/esphome/espota2.py @@ -154,6 +154,12 @@ def check_error(data: list[int] | bytes, expect: int | list[int] | None) -> None """ if not expect: return + if not data: + raise OTAError( + "Error: Device closed connection without responding. " + "This may indicate the device ran out of memory, " + "a network issue, or the connection was interrupted." + ) dat = data[0] if dat == RESPONSE_ERROR_MAGIC: raise OTAError("Error: Invalid magic byte") diff --git a/tests/unit_tests/test_espota2.py b/tests/unit_tests/test_espota2.py index 02f965782b..1885b769f1 100644 --- a/tests/unit_tests/test_espota2.py +++ b/tests/unit_tests/test_espota2.py @@ -192,6 +192,20 @@ def test_check_error_unexpected_response() -> None: espota2.check_error([0x7F], [espota2.RESPONSE_OK, espota2.RESPONSE_AUTH_OK]) +def test_check_error_empty_data() -> None: + """Test check_error raises error when device closes connection without responding.""" + with pytest.raises( + espota2.OTAError, match="Device closed connection without responding" + ): + espota2.check_error([], [espota2.RESPONSE_OK]) + + # Also test with empty bytes + with pytest.raises( + espota2.OTAError, match="Device closed connection without responding" + ): + espota2.check_error(b"", [espota2.RESPONSE_OK]) + + def test_send_check_with_various_data_types(mock_socket: Mock) -> None: """Test send_check handles different data types."""