`mpremote mip install` hangs when uploading files
Port, board and/or hardware
STM32 port on a NUCLEO-144--F767ZI
MicroPython version
MicroPython v1.27.0-preview.440.ga6864109db on 2025-11-23; NUCLEO-F767ZI with STM32F767
Reproduction
- (Optional) Perform a mass erase on all flash blocks.
- Build main firmware and mboot, then upload image to the board with
deploy-stlink - Reboot the board
- Run
mpremote mip install unittest - Wait until it hangs
Expected behaviour
mpremote mip should install the required package
Observed behaviour
The upload process hangs at random intervals, and when stopping it via CTRL+C the traceback is as follows (the process was stopped after a few minutes of being stuck at 13%):
Traceback (most recent call last):
File "/home/agatti/src/micropython/ports/stm32/../../tools/mpremote/mpremote.py", line 6, in <module>
sys.exit(main.main())
~~~~~~~~~^^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/main.py", line 614, in main
handler_func(state, args)
~~~~~~~~~~~~^^^^^^^^^^^^^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/mip.py", line 206, in do_mip
_install_package(
~~~~~~~~~~~~~~~~^
state.transport,
^^^^^^^^^^^^^^^^
...<4 lines>...
args.mpy,
^^^^^^^^^
)
^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/mip.py", line 169, in _install_package
_install_json(transport, package, index, target, version, mpy)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/mip.py", line 131, in _install_json
_download_file(transport, file_url, fs_target_path)
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/mip.py", line 99, in _download_file
transport.fs_writefile(dest, data, progress_callback=show_progress_bar)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/transport.py", line 163, in fs_writefile
self.exec("w(" + repr(chunk) + ")")
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/transport_serial.py", line 309, in exec
ret, ret_err = self.exec_raw(command, data_consumer=data_consumer)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/transport_serial.py", line 295, in exec_raw
self.exec_raw_no_follow(command)
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/transport_serial.py", line 273, in exec_raw_no_follow
return self.raw_paste_write(command_bytes)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
File "/home/agatti/src/micropython/tools/mpremote/mpremote/transport_serial.py", line 228, in raw_paste_write
data = self.serial.read(1)
File "/usr/lib/python3.13/site-packages/serial/serialposix.py", line 565, in read
ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt
The firmware is still waiting for data to arrive on the serial port when mpremote seems to be stuck:
^C
Program received signal SIGINT, Interrupt.
mp_hal_stdin_rx_chr () at mphalport.c:53
53 for (;;) {
08:14:08 mp_hal_stdin_rx_chr > bt
#0 mp_hal_stdin_rx_chr () at mphalport.c:53
#1 0x08068aec in mp_reader_stdin_readbyte (data=0x2007ff74)
at ../../shared/runtime/pyexec.c:255
#2 0x08023164 in next_char (lex=lex@entry=0x20037b50) at ../../py/lexer.c:174
#3 0x08023456 in parse_string_literal (lex=0x20037b50, is_raw=false,
is_fstring=false) at ../../py/lexer.c:413
#4 mp_lexer_to_next (lex=lex@entry=0x20037b50) at ../../py/lexer.c:696
#5 0x0802443c in mp_parse (lex=lex@entry=0x20037b50,
input_kind=input_kind@entry=MP_PARSE_FILE_INPUT) at ../../py/parse.c:1167
#6 0x08068be8 in parse_compile_execute (source=source@entry=0x2007ff7c,
input_kind=input_kind@entry=MP_PARSE_FILE_INPUT,
exec_flags=exec_flags@entry=65) at ../../shared/runtime/pyexec.c:111
#7 0x08068d90 in do_reader_stdin (c=65) at ../../shared/runtime/pyexec.c:324
#8 pyexec_raw_repl () at ../../shared/runtime/pyexec.c:567
#9 0x080730d4 in stm32_main (reset_mode=<optimized out>) at main.c:718
#10 <signal handler called>
in fact, reconnecting to the serial port will find the interpreter still waiting for data to arrive.
Additional Information
No, I've provided everything above.
Code of Conduct
Yes, I agree
tools/mpremote: Fix mpremote mip install with multiple lib folders in sys.path.
This is a fix for an algorithmic error in mpremote mip,
that throws an error due to a \n used in the concatenation and split.
The issue is is discussed in https://github.com/orgs/micropython/discussions/14078
Repro & manual test:
-
connect a pybv11 with an SD card
on start the pybv11 will mount the SD card and add a 2nd../lib-path to sys.path, which will trigger the error.
sys.path:['', '.frozen', '/sd', '/sd/lib', '/flash', '/flash/lib'] -
mpremote mip install requests- Expected result:
Install requests Installing requests (latest) from https://micropython.org/pi/v2 to /sd/lib Installing: /sd/lib/requests/__init__.mpy Done
- Expected result:
<details><summary>Sample error without this fix</summary>
<p>
Install requests
Installing requests (latest) from https://micropython.org/pi/v2 to /sd/lib
/requests/init.mpy
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in run_code
File "C:\Users\josverl\pipx.cache\493badebc2c62e8\Scripts\mpremote.exe_main.py", line 7, in <module>
File "C:\Users\josverl\pipx.cache\493badebc2c62e8\Lib\site-packages\mpremote\main.py", line 528, in main
handler_func(state, args)
File "C:\Users\josverl\pipx.cache\493badebc2c62e8\Lib\site-packages\mpremote\mip.py", line 197, in do_mip
_install_package(
File "C:\Users\josverl\pipx.cache\493badebc2c62e8\Lib\site-packages\mpremote\mip.py", line 160, in _install_package
_install_json(transport, package, index, target, version, mpy)
File "C:\Users\josverl\pipx.cache\493badebc2c62e8\Lib\site-packages\mpremote\mip.py", line 118, in _install_json
_download_file(transport, file_url, fs_target_path)
File "C:\Users\josverl\pipx.cache\493badebc2c62e8\Lib\site-packages\mpremote\mip.py", line 91, in _download_file
_ensure_path_exists(transport, dest)
File "C:\Users\josverl\pipx.cache\493badebc2c62e8\Lib\site-packages\mpremote\mip.py", line 33, in _ensure_path_exists
transport.fs_mkdir(prefix)
File "C:\Users\josverl\pipx.cache\493badebc2c62e8\Lib\site-packages\mpremote\transport_serial.py", line 427, in fs_mkdir
self.exec("import os\nos.mkdir('%s')" % dir)
File "C:\Users\josverl\pipx.cache\493badebc2c62e8\Lib\site-packages\mpremote\transport_serial.py", line 287, in exec
raise TransportError("exception", ret, ret_err)
mpremote.transport.TransportError: ('exception', b'', b'Traceback (most recent call last):\r\n File "<stdin>", line 2\r\nSyntaxError: invalid syntax\r\n')
</p>
</details>