Skip to content

[Bug] Install reports failure despite successful OTA when build log contains 'No module named pip' #918

@swoboda1337

Description

@swoboda1337

What happened

An install completed end-to-end successfully — build succeeded, OTA succeeded, the new firmware is on the device and running — but the dashboard's Install dialog shows a red "Install failed" banner.

Discord report: https://discord.com/channels/429907082951524364/1506842338750628020

The log tail makes it obvious that the underlying ESPHome process succeeded:

[SUCCESS] Took 260.63 seconds
INFO Build Info: config_hash=0xa26c8852 build_time_str=2026-05-20 20:51:43 -0500
INFO Successfully compiled program.
INFO Connecting to 2603:8081:1607:f280:8a56:a6ff:fe6e:4820 port 3232 ...
INFO Connected to 2603:8081:1607:f280:8a56:a6ff:fe6e:4820
Uploading: [============================================================] 100% Done...
INFO Upload took 10.99 seconds, waiting for result...
INFO OTA successful
INFO Successfully uploaded program.

(Full log attached below.)

Root cause

controllers/firmware/runner.py:176 requires both exit_code == 0 and not has_error_in_output:

success = exit_code == 0 and not has_error_in_output

has_error_in_output is set when any output line matches a substring in _ERROR_PATTERNS (controllers/firmware/constants.py:30):

https://github.com/esphome/device-builder/blob/main/esphome_device_builder/controllers/firmware/constants.py#L30-L36

_ERROR_PATTERNS = [
    "ModuleNotFoundError",
    "ImportError",
    "No module named",       # <-- too loose
    "FileNotFoundError",
    "command not found",
]

This build's PlatformIO output contains:

[nanopb] Installing Protocol Buffers dependencies
/root/.platformio/penv/bin/python: No module named pip
[nanopb] Installing gRPC dependencies
/root/.platformio/penv/bin/python: No module named pip
[nanopb] No generation needed.

PlatformIO's [nanopb] extra-script tries to bootstrap pip inside the PIO venv (which doesn't ship pip), fails harmlessly, and proceeds. The next line is [nanopb] No generation needed. — generation already done from cache. The build is fine.

But the bare substring "No module named" matches, has_error_in_output flips True, and even though exit_code == 0 and the OTA logs success, the dashboard reports failure.

Suggested fix

Drop the bare substring. The remaining patterns (ModuleNotFoundError, ImportError, FileNotFoundError, command not found) already cover Python tracebacks that surface real failures, and the specific _NO_ESPHOME_MODULE_MARKER = "No module named 'esphome'" at constants.py:42 still handles the saw_no_esphome_module branch that produces the actionable error message:

_ERROR_PATTERNS = [
    "ModuleNotFoundError",
    "ImportError",
    "FileNotFoundError",
    "command not found",
]

A narrower alternative (keep the substring but anchor on the quoted form CPython actually prints) would also work:

_ERROR_PATTERNS = [
    ...,
    "No module named '",   # CPython prints quoted module names; PlatformIO's "python: No module named pip" doesn't match
]

Reproduction

Any device config that exercises the [nanopb] extra-script via a PIO library that pulls it in (the reporter's config uses noise-c via the TeslaBLE component). Install via the dashboard. PIO logs the four No module named pip lines; dashboard ends with the red banner despite a successful OTA.

Logs

Full tesla-ble-6e4820 install log (tail)
Reading CMake configuration...
[nanopb] Installing Protocol Buffers dependencies
/root/.platformio/penv/bin/python: No module named pip
[nanopb] Installing gRPC dependencies
/root/.platformio/penv/bin/python: No module named pip
[nanopb] No generation needed.
Generating assembly for certificate bundle...
[nanopb] Installing Protocol Buffers dependencies
/root/.platformio/penv/bin/python: No module named pip
[nanopb] Installing gRPC dependencies
/root/.platformio/penv/bin/python: No module named pip
[nanopb] No generation needed.
Dependency Graph
|-- TeslaBLE @ 2026.5.0+sha.e63742c
|-- noise-c @ 0.1.11
... (compile + link, all clean) ...
RAM:   [==        ]  18.1% (used 59212 bytes from 327680 bytes)
Flash: [========  ]  79.9% (used 1465986 bytes from 1835008 bytes)
=========================== [SUCCESS] Took 260.63 seconds ===========================
INFO Build Info: config_hash=0xa26c8852 build_time_str=2026-05-20 20:51:43 -0500
INFO Successfully compiled program.
INFO Connecting to 2603:8081:1607:f280:8a56:a6ff:fe6e:4820 port 3232 ...
INFO Connected to 2603:8081:1607:f280:8a56:a6ff:fe6e:4820
Uploading: [============================================================] 100% Done...
INFO Upload took 10.99 seconds, waiting for result...
INFO OTA successful
INFO Successfully uploaded program.

Workaround for users

The firmware is installed; the banner is wrong. Confirm the device is online and running the new firmware (the device card on the dashboard or HA will show it). No action needed beyond closing the dialog.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions