Title: Build silently produces broken firmware when submodules aren't initialised (dangling symlinks) · Issue #149 · MicroPythonOS/MicroPythonOS · GitHub
Open Graph Title: Build silently produces broken firmware when submodules aren't initialised (dangling symlinks) · Issue #149 · MicroPythonOS/MicroPythonOS
X Title: Build silently produces broken firmware when submodules aren't initialised (dangling symlinks) · Issue #149 · MicroPythonOS/MicroPythonOS
Description: Summary internal_filesystem/lib/nostr is a symlink to ../../micropython-nostr/nostr/. If the micropython-nostr submodule hasn't been populated (i.e. the user cloned MPOS without --recurse-submodules and didn't run git submodule update --...
Open Graph Description: Summary internal_filesystem/lib/nostr is a symlink to ../../micropython-nostr/nostr/. If the micropython-nostr submodule hasn't been populated (i.e. the user cloned MPOS without --recurse-submodule...
X Description: Summary internal_filesystem/lib/nostr is a symlink to ../../micropython-nostr/nostr/. If the micropython-nostr submodule hasn't been populated (i.e. the user cloned MPOS without --recurse-submo...
Opengraph URL: https://github.com/MicroPythonOS/MicroPythonOS/issues/149
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Build silently produces broken firmware when submodules aren't initialised (dangling symlinks)","articleBody":"## Summary\n\n`internal_filesystem/lib/nostr` is a symlink to `../../micropython-nostr/nostr/`. If the `micropython-nostr` submodule hasn't been populated (i.e. the user cloned MPOS without `--recurse-submodules` and didn't run `git submodule update --init --recursive` after), the symlink dangles, and the manifest's `freeze('../internal_filesystem/lib', '')` step **silently skips it** — no error, no warning. The build succeeds and produces a firmware that's missing the `nostr` module.\n\nAny app that depends on `nostr` (e.g. Lightning Piggy's `nwc_wallet.py`) then fails at runtime with `ImportError: no module named 'nostr'` when launched. From the user's perspective the app just doesn't open — no obvious clue from the build log.\n\nThis bit me while testing an unrelated firmware change; LP wouldn't launch after a fresh build and it took a serial-REPL session to surface the actual cause.\n\n## Reproduction\n\n```bash\ngit clone https://github.com/MicroPythonOS/MicroPythonOS.git\ncd MicroPythonOS\ngit submodule update --init lvgl_micropython # but not micropython-nostr\n./scripts/build_mpos.sh esp32s3\n# Build succeeds. Flash the firmware. Try to launch Lightning Piggy. ImportError.\n```\n\nConfirm by inspecting `frozen_content.c`:\n\n```bash\ngrep -c nostr lvgl_micropython/lib/micropython/ports/esp32/build-*/frozen_content.c\n# 0 — the freezer silently dropped the dangling symlink\n```\n\nThe same trap potentially applies to any other symlink under `internal_filesystem/lib/` that points into an un-init'd submodule. Today only `nostr` is structured this way (`find internal_filesystem/lib -maxdepth 2 -type l` is just the one entry), but the failure mode is generic.\n\n## Suggested fix\n\nTwo complementary safety-nets, take either or both:\n\n1. **`build_mpos.sh` pre-flight check** — before invoking `make.py`, walk `internal_filesystem/lib/` for symlinks and verify each one resolves. Abort with a clear error like:\n ```\n ERROR: internal_filesystem/lib/nostr -\u003e ../../micropython-nostr/nostr/\n target does not exist. Run:\n git submodule update --init --recursive\n and try again.\n ```\n2. **Eager submodule init at the top of `build_mpos.sh`** — `git submodule update --init` for the MPOS-side siblings that are known build inputs (`micropython-nostr`, `secp256k1-embedded-ecdh`, `c_mpos`, `micropython-camera-API`). Cheap on subsequent builds (no-op if already populated), bulletproof on fresh clones.\n\nHappy to send a PR for either approach if there's a preference.","author":{"url":"https://github.com/bitcoin3us","@type":"Person","name":"bitcoin3us"},"datePublished":"2026-05-30T20:38:08.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/149/MicroPythonOS/issues/149"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:775068dd-9d3b-e24b-8a01-6d2ea8f58dd9 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | C818:310BDB:43BC597:5EBA337:6A4F703D |
| html-safe-nonce | 06905328e9295b98c09a95887b5c62914a3fc30a6eaeb2832a119d3fc12df0bf |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDODE4OjMxMEJEQjo0M0JDNTk3OjVFQkEzMzc6NkE0RjcwM0QiLCJ2aXNpdG9yX2lkIjoiNTAyMzQ3MDI1MzE0MjY2NzMyNiIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 4081709723cdc8e832f87ecbce1fff6d7fee028c0ec885cabd413997fdcb3582 |
| hovercard-subject-tag | issue:4555626223 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/MicroPythonOS/MicroPythonOS/149/issue_layout |
| twitter:image | https://opengraph.githubassets.com/a7a8e201da9cb08c5b6872d8ec5368e40d4e58fdf39c469969e1c9a8e4967777/MicroPythonOS/MicroPythonOS/issues/149 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/a7a8e201da9cb08c5b6872d8ec5368e40d4e58fdf39c469969e1c9a8e4967777/MicroPythonOS/MicroPythonOS/issues/149 |
| og:image:alt | Summary internal_filesystem/lib/nostr is a symlink to ../../micropython-nostr/nostr/. If the micropython-nostr submodule hasn't been populated (i.e. the user cloned MPOS without --recurse-submodule... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | bitcoin3us |
| hostname | github.com |
| expected-hostname | github.com |
| None | b92d11c0aa4a77d54ef4af1078b6a15fb5a70a215b30c4ecf28889d5a8e656d9 |
| turbo-cache-control | no-preview |
| go-import | github.com/MicroPythonOS/MicroPythonOS git https://github.com/MicroPythonOS/MicroPythonOS.git |
| octolytics-dimension-user_id | 213598128 |
| octolytics-dimension-user_login | MicroPythonOS |
| octolytics-dimension-repository_id | 975472483 |
| octolytics-dimension-repository_nwo | MicroPythonOS/MicroPythonOS |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 975472483 |
| octolytics-dimension-repository_network_root_nwo | MicroPythonOS/MicroPythonOS |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 4b249b445842943ed31549e027f57a8ade9881ed |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width