esp-bmgr-assist
esp-bmgr-assist is BMGR’s Python helper package (source code located at tools/esp_bmgr_assist/ in the repository). It hooks into the idf.py startup process via a .pth hook, automatically discovers the esp_board_manager component used by the current project, and adds it to IDF_EXTRA_ACTIONS_PATH, making the idf.py bmgr command directly available without manual environment variable configuration.
It does not replace the esp_board_manager component and does not generate board-level code; board-level code is still generated by gen_bmgr_config_codes.py inside the component.
Installation
Activate the ESP-IDF Python environment first (run ./install.sh and . ./export.sh in the IDF directory), then execute:
pip install esp-bmgr-assist
Upgrade:
pip install --upgrade esp-bmgr-assist
Install from local source in the repository:
pip install --no-build-isolation ./tools/esp_bmgr_assist
Re-installation is required after switching to a new ESP-IDF Python environment.
Auto-Discovery Rules
esp-bmgr-assist searches for the esp_board_manager component in the current project in the following order:
components/esp_board_managercomponents/espressif__esp_board_managermanaged_components/espressif__esp_board_managerLocal component pointed to by
override_path/pathinidf_component.ymlesp_board_managerresolved fromdependencies.lockespressif/esp_board_manageras a direct or indirect dependency in the project dependency graph
Only a directory that simultaneously contains idf_ext.py, idf_component.yml, and gen_bmgr_config_codes.py is recognized as a valid component directory.
When idf.py bmgr ... is executed for the first time and the managed component has not yet been downloaded, the helper tool triggers dependency resolution and downloads esp_board_manager, then loads the Board Manager action after the download completes.
Pre-Build Checks
When commands such as idf.py build are executed, esp-bmgr-assist first checks:
Whether the generated artifacts in
components/gen_bmgr_codes/*are missing.Whether
CONFIG_IDF_TARGETinsdkconfigandgen_bmgr_codes/board_manager.defaultsare inconsistent.
By default, the command is aborted when an issue is detected. Adjust the severity level via a parameter or environment variable:
idf.py --bmgr-preflight-level warning build # print warning only
idf.py --bmgr-preflight-level silent build # skip
export ESP_BMGR_ASSIST_PREFLIGHT=warning # equivalent environment variable
Supported levels: error / abort (default), warning / warn, silent / off. The pre-build check only applies to build-type commands and does not interfere with interactive or configuration commands such as set-target, menuconfig, or confserver.
Debugging and Fallback
Debug the auto-discovery process:
export ESP_BMGR_DEBUG=1
idf.py bmgr -l
Fallback: when esp-bmgr-assist is not installed or auto-discovery fails, manually set IDF_EXTRA_ACTIONS_PATH to point to the esp_board_manager component directory (separate multiple paths with ;, not :).
Known Issues
Falling Back to esp32 Target on Indirect Dependencies
If esp_board_manager is introduced indirectly through an upstream component (i.e., not declared directly in main/idf_component.yml), the helper tool needs to resolve the full dependency graph and relies on IDF_TARGET to produce correct results. When it cannot be read, it falls back to esp32, which may cause dependency resolution failures for components that only support specific targets.
Workaround:
Run
idf.py set-target <target>to fetch the ESP Board Manager component.Or temporarily specify the target when running Board Manager commands:
IDF_TARGET=esp32s3 idf.py bmgr -l
ESP_BMGR_BOOTSTRAP_TARGET=esp32p4 idf.py bmgr -b <board>
When the project declares espressif/esp_board_manager directly in main/idf_component.yml, the minimal download path is used and this issue typically does not occur.
Command Appears to Hang While Waiting for Bootstrap Lock
esp-bmgr-assist uses a .esp_bmgr_py.lock file in the project directory to serialize the bootstrap process between multiple idf.py processes, preventing concurrent component downloads. If another idf.py command in the same project directory is currently bootstrapping or downloading components, the new command waits for this lock first.
When waiting starts, a message is printed, for example:
[esp-bmgr-assist] Waiting for board manager bootstrap lock.
lock: /path/to/project/.esp_bmgr_py.lock
timeout: 60s
If this waits unexpectedly, check the process holding the lock:
lsof /path/to/project/.esp_bmgr_py.lock
fuser -v /path/to/project/.esp_bmgr_py.lock
The default timeout is 60 seconds. After the timeout, Timed out waiting for board manager bootstrap lock. is printed and the command is aborted. The lsof / fuser -v commands shown in the message apply to Linux and macOS. Windows users refer to the platform-specific troubleshooting steps below.
Troubleshooting steps:
Confirm whether a real
idf.py/pythonprocess is holding the lock.Linux / macOS:
lsof /path/to/project/.esp_bmgr_py.lock fuser -v /path/to/project/.esp_bmgr_py.lock
Windows: use Sysinternals
handle.exe, or open Task Manager / Resource Monitor (resmon.exe), go to CPU > Associated Handles, and search for the lock file name:handle.exe \path\to\project\.esp_bmgr_py.lock
If no process is holding the lock (for example, the lock file was left behind by a killed command), delete the lock file manually and retry:
Linux / macOS:
rm /path/to/project/.esp_bmgr_py.lockWindows (cmd):
del \path\to\project\.esp_bmgr_py.lockWindows (PowerShell):
Remove-Item \path\to\project\.esp_bmgr_py.lock
When the project directory is not writable, the lock file falls back to
esp_bmgr_py_locks/<digest>.lockin the system temporary directory (typically/tmp/on Linux/macOS,%TEMP%on Windows). The message shows the exact path.To allow a longer wait window (for example, when fetching the component for the first time is slow), adjust the timeout:
Linux / macOS:
export ESP_BMGR_LOCK_TIMEOUT=120
Windows (cmd):
set ESP_BMGR_LOCK_TIMEOUT=120
Windows (PowerShell):
$env:ESP_BMGR_LOCK_TIMEOUT = "120"
Full documentation: esp_board_manager/docs/esp_bmgr_assist_cn.md.
Options Not Recognized After Switching IDF Versions
After switching to a different IDF version, idf.py bmgr may report unrecognized options, for example:
>> idf.py bmgr -l
Usage: idf.py bmgr [OPTIONS]
Try 'idf.py bmgr --help' for help.
Error: No such option: -l
Each ESP-IDF version uses an isolated Python virtual environment. After switching versions, esp-bmgr-assist may not be installed in the new environment.
Resolution:
Check whether the package is present in the current IDF Python environment:
pip show esp-bmgr-assist
If no package information is shown, reinstall or upgrade it in the current IDF environment:
python3 -m pip install --upgrade esp-bmgr-assist