From e7c5b15f348227434fb9f3155bee4b1ff4466088 Mon Sep 17 00:00:00 2001 From: szmidtpiotr Date: Fri, 28 Aug 2026 18:17:44 +0200 Subject: [PATCH] Fix ESP32 repeater boot crash-loop on blank/first-boot flash SPIFFS.begin(true) in the repeater's setup() ignored its return value. On a freshly erased flash the initial mount can fail, and the format-on-fail path built into SPIFFS.begin() can itself fail on the first attempt. Previously the code carried on regardless, leaving fs/IdentityStore/CommonCLI/ClientACL/RegionMap all operating against a non-functional filesystem. Reads against SPIFFS in that state don't fail cleanly - they can return stale/garbage data - which corrupts node prefs/ACL/region state and crashes shortly after boot (StoreProhibited / IllegalInstruction, register contents matching raw erased-flash bytes). The device then reboots into the same broken state, producing a permanent crash-loop. Fix: check SPIFFS.begin(true)'s return value; on failure, retry with an explicit SPIFFS.format() + SPIFFS.begin(), and halt with a clear log message if it still fails, instead of silently continuing with a broken filesystem. Verified on physical Heltec V4 (ESP32-S3, 2MB PSRAM/16MB flash) hardware: full chip erase + reflash of the repeater firmware previously crash-looped every boot; with this fix the device boots cleanly and stably from blank flash. Fixes #2506 --- examples/simple_repeater/main.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index a714db68ec..609ce7745b 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -73,7 +73,18 @@ void setup() { fs = &InternalFS; IdentityStore store(InternalFS, ""); #elif defined(ESP32) - SPIFFS.begin(true); + if (!SPIFFS.begin(true)) { + // format-on-mount-fail can itself fail on some boards/first-boots (blank flash). + // Retry with an explicit format before giving up, otherwise callers below will + // read/write against a non-mounted filesystem and get garbage back instead of + // clean failures (observed as SPIFFS mount errors followed by a boot crash-loop). + MESH_DEBUG_PRINTLN("SPIFFS mount failed, retrying with explicit format"); + SPIFFS.format(); + if (!SPIFFS.begin(true)) { + MESH_DEBUG_PRINTLN("SPIFFS mount failed after format, halting"); + halt(); + } + } fs = &SPIFFS; IdentityStore store(SPIFFS, "/identity"); #elif defined(RP2040_PLATFORM)