- reference/architecture/controller/multi-controller-sync.md: - Added Checksum Validation section with strict/permissive modes - Documented checksum failure handling flow diagram - Added Checksum Validation Modes subsection under Error Handling - Updated Implementation Status with new features - reference/architecture/controller/event-system.md: - Added new Multi-Controller Sync Events section - Documented CLEARGROW_EVENT_SYNC_CHECKSUM_FAILED event - Added sync_checksum_type_t enum and event data structure - Included example handler code - reference/errors/error-codes.md: - Added Configuration Error Codes subsection - Documented error code 0x0039 for sync checksum mismatch - Updated ERROR_CAT_CONFIG example errors 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
29 KiB
title, version, last_updated
| title | version | last_updated |
|---|---|---|
| Error Codes Reference | 2.1 | 2025-12-11 |
Error Codes Reference
Complete reference for ClearGrow error codes, categories, and error handling patterns.
Overview
ClearGrow uses ESP-IDF's standard esp_err_t return type for all functions that can fail. Error codes are 16-bit unsigned integers with defined ranges:
| Range | Owner | Purpose |
|---|---|---|
0x0000 |
ESP-IDF | Success (ESP_OK) |
0x0001-0x00FF |
ESP-IDF | Generic errors |
0x0100-0x4FFF |
ESP-IDF | Component-specific errors |
0x5000-0x5FFF |
ClearGrow | Custom application errors |
Error Code Format
ESP-IDF Standard Format
typedef uint32_t esp_err_t;
#define ESP_OK 0x0 // Success
#define ESP_FAIL 0x1 // Generic failure
// Component errors: 0xCCNN where CC=component, NN=error number
ClearGrow Custom Format
#define ESP_ERR_CLEARGROW_BASE 0x5000
#define ESP_ERR_COMPONENT_ERROR (BASE + offset)
Each ClearGrow component reserves a 16-code range (0x10 codes per component).
Error Severity Levels
| Level | Log Function | Meaning | System Behavior | LED Pattern |
|---|---|---|---|---|
| CRITICAL | ESP_ERROR_CHECK() |
System cannot function | Panic, restart system | SOS pattern |
| ERROR | ESP_LOGE() |
Operation failed | Log, return error to caller | Fast blink (6+ errors) |
| WARNING | ESP_LOGW() |
Unexpected but handled | Log, continue with fallback | Slow blink (1-5 errors) |
| INFO | ESP_LOGI() |
Normal operation | Log informational event | Solid ON |
| DEBUG | ESP_LOGD() |
Debug information | Log detailed trace (dev only) | N/A |
See Status LED Reference for detailed LED pattern descriptions.
Standard ESP-IDF Error Codes
Generic Errors (0x0001-0x00FF)
| Code (Hex) | Code (Dec) | Name | Description | Typical Cause |
|---|---|---|---|---|
0x0000 |
0 | ESP_OK |
Success | Operation completed successfully |
0x0001 |
1 | ESP_FAIL |
Generic failure | Unspecified error |
0x0101 |
257 | ESP_ERR_NO_MEM |
Out of memory | Heap exhausted, allocation failed |
0x0102 |
258 | ESP_ERR_INVALID_ARG |
Invalid argument | NULL pointer, out of range value |
0x0103 |
259 | ESP_ERR_INVALID_STATE |
Invalid state | Component not initialized, wrong state |
0x0104 |
260 | ESP_ERR_INVALID_SIZE |
Invalid size | Buffer too small, size mismatch |
0x0105 |
261 | ESP_ERR_NOT_FOUND |
Not found | Key, entry, device not found |
0x0106 |
262 | ESP_ERR_NOT_SUPPORTED |
Not supported | Feature disabled, unsupported operation |
0x0107 |
263 | ESP_ERR_TIMEOUT |
Operation timed out | Network timeout, mutex timeout |
0x0108 |
264 | ESP_ERR_INVALID_RESPONSE |
Invalid response | Protocol error, corrupt data |
0x0109 |
265 | ESP_ERR_INVALID_CRC |
CRC check failed | Data corruption detected |
0x010A |
266 | ESP_ERR_INVALID_VERSION |
Invalid version | Incompatible version number |
0x010B |
267 | ESP_ERR_INVALID_MAC |
Invalid MAC address | Malformed MAC address |
NVS Errors (0x1100-0x11FF)
| Code (Hex) | Code (Dec) | Name | Description | Recovery |
|---|---|---|---|---|
0x1101 |
4353 | ESP_ERR_NVS_BASE |
NVS base error | Check NVS partition |
0x1102 |
4354 | ESP_ERR_NVS_NOT_INITIALIZED |
NVS not initialized | Call nvs_flash_init() |
0x1103 |
4355 | ESP_ERR_NVS_NOT_FOUND |
Key not found | Use default value, or save key first |
0x1104 |
4356 | ESP_ERR_NVS_TYPE_MISMATCH |
Type mismatch | Key exists with different type |
0x1105 |
4357 | ESP_ERR_NVS_READ_ONLY |
Read-only handle | Open handle with write access |
0x1106 |
4358 | ESP_ERR_NVS_NOT_ENOUGH_SPACE |
Not enough space | Free space, erase, or increase partition |
0x1107 |
4359 | ESP_ERR_NVS_INVALID_NAME |
Invalid name | Name too long (>15 chars) |
0x1108 |
4360 | ESP_ERR_NVS_INVALID_HANDLE |
Invalid handle | Handle closed or never opened |
0x1109 |
4361 | ESP_ERR_NVS_REMOVE_FAILED |
Remove failed | Key doesn't exist or write error |
0x110A |
4362 | ESP_ERR_NVS_KEY_TOO_LONG |
Key too long | Max 15 characters |
0x110B |
4363 | ESP_ERR_NVS_PAGE_FULL |
Page full | Internal error, try erase |
0x110C |
4364 | ESP_ERR_NVS_INVALID_STATE |
Invalid state | NVS corrupted, erase and reinit |
0x110D |
4365 | ESP_ERR_NVS_INVALID_LENGTH |
Invalid length | Buffer too small for value |
0x1112 |
4370 | ESP_ERR_NVS_NO_FREE_PAGES |
No free pages | NVS full, erase or increase partition |
0x1113 |
4371 | ESP_ERR_NVS_VALUE_TOO_LONG |
Value too long | Reduce value size or use blob |
0x1114 |
4372 | ESP_ERR_NVS_PART_NOT_FOUND |
Partition not found | Check partition table |
0x1117 |
4375 | ESP_ERR_NVS_NEW_VERSION_FOUND |
New version found | Automatic migration available |
0x1118 |
4376 | ESP_ERR_NVS_XTS_ENCR_FAILED |
Encryption failed | NVS encryption error |
0x1119 |
4377 | ESP_ERR_NVS_XTS_DECR_FAILED |
Decryption failed | NVS key invalid or corrupted |
0x111A |
4378 | ESP_ERR_NVS_XTS_CFG_FAILED |
Encryption config failed | Check NVS encryption settings |
0x111B |
4379 | ESP_ERR_NVS_XTS_CFG_NOT_FOUND |
Encryption config not found | Initialize NVS encryption |
0x111C |
4380 | ESP_ERR_NVS_ENCR_NOT_SUPPORTED |
Encryption not supported | Build with CONFIG_NVS_ENCRYPTION |
0x111D |
4381 | ESP_ERR_NVS_KEYS_NOT_INITIALIZED |
Keys not initialized | Generate NVS encryption keys |
0x111E |
4382 | ESP_ERR_NVS_CORRUPT_KEY_PART |
Key partition corrupt | Re-flash NVS keys partition |
WiFi Errors (0x3000-0x30FF)
| Code (Hex) | Code (Dec) | Name | Description | Recovery |
|---|---|---|---|---|
0x3001 |
12289 | ESP_ERR_WIFI_NOT_INIT |
WiFi not initialized | Call esp_wifi_init() |
0x3002 |
12290 | ESP_ERR_WIFI_NOT_STARTED |
WiFi not started | Call esp_wifi_start() |
0x3003 |
12291 | ESP_ERR_WIFI_NOT_STOPPED |
WiFi not stopped | Call esp_wifi_stop() first |
0x3004 |
12292 | ESP_ERR_WIFI_IF |
Invalid interface | Check WiFi mode (STA/AP) |
0x3005 |
12293 | ESP_ERR_WIFI_MODE |
Invalid mode | Set mode before operation |
0x3006 |
12294 | ESP_ERR_WIFI_STATE |
Invalid WiFi state | Check WiFi state machine |
0x3007 |
12295 | ESP_ERR_WIFI_CONN |
WiFi connection failed | Check credentials, signal |
0x3008 |
12296 | ESP_ERR_WIFI_NVS |
WiFi NVS error | Erase WiFi NVS namespace |
0x3009 |
12297 | ESP_ERR_WIFI_MAC |
MAC address error | Invalid or duplicate MAC |
0x300A |
12298 | ESP_ERR_WIFI_SSID |
SSID invalid | Check SSID length (0-32) |
0x300B |
12299 | ESP_ERR_WIFI_PASSWORD |
Password invalid | Check password length (8-64) |
0x300C |
12300 | ESP_ERR_WIFI_TIMEOUT |
Connection timeout | Retry, check signal strength |
0x300D |
12301 | ESP_ERR_WIFI_WAKE_FAIL |
Wake from sleep failed | Reinitialize WiFi |
0x300E |
12302 | ESP_ERR_WIFI_WOULD_BLOCK |
Would block | Retry later |
0x300F |
12303 | ESP_ERR_WIFI_NOT_CONNECT |
Not connected | Connect before operation |
HTTP Errors (0x7000-0x70FF)
| Code (Hex) | Code (Dec) | Name | Description | Recovery |
|---|---|---|---|---|
0x7001 |
28673 | ESP_ERR_HTTP_BASE |
HTTP base error | Check HTTP logs |
0x7002 |
28674 | ESP_ERR_HTTP_CONNECT |
Connection failed | Check network, URL |
0x7003 |
28675 | ESP_ERR_HTTP_WRITE_DATA |
Write failed | Check connection |
0x7004 |
28676 | ESP_ERR_HTTP_FETCH_HEADER |
Header fetch failed | Invalid response |
0x7005 |
28677 | ESP_ERR_HTTP_INVALID_TRANSPORT |
Invalid transport | Use HTTP/HTTPS correctly |
0x7006 |
28678 | ESP_ERR_HTTP_CONNECTING |
Connection in progress | Wait for completion |
0x7007 |
28679 | ESP_ERR_HTTP_EAGAIN |
Try again | Retry operation |
Flash/Partition Errors (0x1500-0x15FF)
| Code (Hex) | Code (Dec) | Name | Description | Recovery |
|---|---|---|---|---|
0x1501 |
5377 | ESP_ERR_FLASH_OP_FAIL |
Flash operation failed | Retry, check flash |
0x1502 |
5378 | ESP_ERR_FLASH_OP_TIMEOUT |
Flash timeout | Check flash chip |
0x1503 |
5379 | ESP_ERR_FLASH_NOT_INITIALISED |
Flash not initialized | Call flash init |
0x1504 |
5380 | ESP_ERR_FLASH_UNSUPPORTED_HOST |
Unsupported host | Check SPI configuration |
0x1505 |
5381 | ESP_ERR_FLASH_UNSUPPORTED_CHIP |
Unsupported chip | Flash chip incompatible |
OTA Errors (0x1500-0x15FF)
| Code (Hex) | Code (Dec) | Name | Description | Recovery |
|---|---|---|---|---|
0x1501 |
5377 | ESP_ERR_OTA_BASE |
OTA base error | Check OTA logs |
0x1502 |
5378 | ESP_ERR_OTA_PARTITION_CONFLICT |
Partition conflict | Check partition table |
0x1503 |
5379 | ESP_ERR_OTA_SELECT_INFO_INVALID |
OTA select invalid | Corrupted OTA data |
0x1504 |
5380 | ESP_ERR_OTA_VALIDATE_FAILED |
Validation failed | Image corrupt or unsigned |
0x1505 |
5381 | ESP_ERR_OTA_SMALL_SEC_VER |
Security version too old | Downgrade not allowed |
0x1506 |
5382 | ESP_ERR_OTA_ROLLBACK_FAILED |
Rollback failed | Both partitions invalid |
0x1507 |
5383 | ESP_ERR_OTA_ROLLBACK_INVALID_STATE |
Invalid rollback state | Complete current boot first |
ClearGrow Custom Error Codes
Storage Component (0x5000-0x500F)
Defined in: /opt/repos/controller/components/storage/include/storage_types.h
| Code (Hex) | Code (Dec) | Name | Description | Cause | Recovery |
|---|---|---|---|---|---|
0x5000 |
20480 | ESP_ERR_STORAGE_BASE |
Storage base error | Generic storage error | Check specific error |
0x5001 |
20481 | ESP_ERR_STORAGE_NOT_MOUNTED |
Storage not mounted | SPIFFS or SD not mounted | Mount storage first |
0x5002 |
20482 | ESP_ERR_STORAGE_FULL |
Storage full | Write failed mid-operation (reactive) | Run recovery, clear history |
0x5003 |
20483 | ESP_ERR_STORAGE_CORRUPT |
Storage corrupted | Filesystem corruption | Reformat storage |
0x5004 |
20484 | ESP_ERR_STORAGE_SD_NOT_PRESENT |
SD card not present | SD card removed/missing | Insert SD card |
0x5005 |
20485 | ESP_ERR_STORAGE_QUERY_CANCELLED |
Query cancelled | User cancelled query | Normal operation |
0x5006 |
20486 | ESP_ERR_STORAGE_NO_DATA |
No data available | Time range has no data | Adjust query parameters |
Note on Storage Free Space Errors:
The standard ESP_ERR_NO_MEM (0x0101) is returned by storage backends when proactive free space checks detect insufficient space before attempting a write. This is different from ESP_ERR_STORAGE_FULL which indicates a write failed mid-operation:
| Error | When Returned | Data Integrity | Meaning |
|---|---|---|---|
ESP_ERR_NO_MEM |
Before write | Safe | Free space insufficient (proactive check) |
ESP_ERR_STORAGE_FULL |
During write | At risk | Write failed mid-operation (reactive) |
Thresholds: SPIFFS requires 50KB headroom, SD card requires 1MB headroom beyond the write size. See Storage Reference for details.
Critical Thresholds (Issue CG-44):
Higher-level storage functions (history_cache, data_logger) perform additional proactive checks:
- SPIFFS: Writes fail with
ESP_ERR_STORAGE_FULLif free space < 25KB (~5% of 512KB) - SD Card: Writes fail with
ESP_ERR_STORAGE_FULLif free space < 10MB
When these thresholds are breached:
- User-actionable error logged to error_log with suggested action
- Status LED pattern changes to
LED_PATTERN_WARNING(slow blink) - REST API
/api/logsexposes error state inspiffs.errorandsd.errorfields
REST API Error States (returned in /api/logs endpoint):
{
"spiffs": {
"mounted": true,
"error": "ok"
},
"sd": {
"present": true,
"error": "ok"
}
}
Possible error values: "ok", "full", "not_mounted", "io_error", "corrupt".
Thread Manager (0x5010-0x501F) [Reserved]
Reserved for future OpenThread-specific errors:
- Border router initialization failures
- RCP communication errors
- Network formation errors
- Code pairing failures
Network API (0x5020-0x502F) [Reserved]
Reserved for REST API and MQTT errors:
- HTTP server errors
- Authentication failures
- MQTT connection errors
- API rate limiting
Automation Engine (0x5030-0x503F) [Reserved]
Reserved for automation errors:
- Rule validation failures
- Action execution errors
- Schedule conflicts
TFLite Runner (0x5040-0x504F) [Reserved]
Reserved for ML inference errors:
- Model loading failures
- Inference errors
- Tensor allocation failures
Security Component (0x5050-0x505F) [Reserved]
Reserved for security/crypto errors:
- Key generation failures
- Encryption/decryption errors
- Signature verification failures
OTA Manager (0x5060-0x506F) [Reserved]
Reserved for OTA update errors:
- Download failures
- Signature verification failures
- Flash write errors
- Rollback errors
UI Component (0x5070-0x507F) [Reserved]
Reserved for UI-specific errors:
- LVGL allocation failures
- Screen transition errors
- Asset loading failures
Error Categories
User-facing errors are categorized for the error log system. Defined in /opt/repos/controller/components/common/include/error_log.h:
| Category | Value | Description | Example Errors |
|---|---|---|---|
ERROR_CAT_WIFI |
0 | WiFi connection issues | Connection failed, weak signal, DHCP timeout |
ERROR_CAT_STORAGE |
1 | Storage full or unavailable | SD card missing, SPIFFS full, corruption |
ERROR_CAT_THREAD |
2 | Thread network issues | Border router init failed, RCP error, pairing failed |
ERROR_CAT_SENSOR |
3 | Sensor communication errors | Probe timeout, invalid reading, sensor malfunction |
ERROR_CAT_OTA |
4 | Firmware update errors | Download failed, verification failed, rollback |
ERROR_CAT_CONFIG |
5 | Configuration errors | Invalid settings, NVS corruption, sync checksum mismatch |
ERROR_CAT_GENERAL |
6 | Other errors | Memory allocation, generic failures |
Configuration Error Codes
Error codes specific to the ERROR_CAT_CONFIG category:
| Code | Description | Cause | Resolution |
|---|---|---|---|
0x0039 |
Sync checksum mismatch | Zone or automation data checksum didn't match after multi-controller sync | In permissive mode: auto-resolved. In strict mode: system requests fresh snapshot from leader (up to 3 retries). Check network stability if frequent. |
Error Handling Patterns
Pattern 1: Critical Initialization
Use ESP_ERROR_CHECK() for errors that should cause system restart:
esp_err_t ret;
// Critical: System cannot function without NVS
ret = nvs_flash_init();
ESP_ERROR_CHECK(ret);
// Critical: Must have event loop
ret = esp_event_loop_create_default();
ESP_ERROR_CHECK(ret);
// Critical: Display is required for UI
ret = display_manager_init();
ESP_ERROR_CHECK(ret);
Behavior: Logs error, triggers panic handler, system restarts.
Use for:
- NVS flash initialization
- Event loop creation
- Display hardware initialization
- Critical timer/peripheral configuration
Pattern 2: Recoverable Errors
Use ESP_RETURN_ON_ERROR() for errors where caller can handle failure:
static const char *TAG = "wifi_mgr";
esp_err_t wifi_connect(const char *ssid, const char *password)
{
esp_err_t ret;
// Initialize WiFi
ret = esp_wifi_init(&cfg);
ESP_RETURN_ON_ERROR(ret, TAG, "WiFi init failed: %s", esp_err_to_name(ret));
// Start WiFi
ret = esp_wifi_start();
ESP_RETURN_ON_ERROR(ret, TAG, "WiFi start failed: %s", esp_err_to_name(ret));
// Connect (may fail - not fatal)
ret = esp_wifi_connect();
ESP_RETURN_ON_ERROR(ret, TAG, "WiFi connect failed: %s", esp_err_to_name(ret));
return ESP_OK;
}
Behavior: Logs error, returns error code to caller.
Use for:
- Network operations (WiFi, Thread, MQTT)
- File operations (SD card, SPIFFS)
- NVS read/write operations
- Optional component initialization
Pattern 3: Parameter Validation
Use ESP_RETURN_ON_FALSE() for precondition checks:
esp_err_t sensor_hub_get_reading(uint64_t probe_id, float *value)
{
static const char *TAG = "sensor_hub";
// Validate parameters
ESP_RETURN_ON_FALSE(value != NULL, ESP_ERR_INVALID_ARG, TAG,
"value pointer is NULL");
ESP_RETURN_ON_FALSE(probe_id != 0, ESP_ERR_INVALID_ARG, TAG,
"probe_id cannot be zero");
// Validate state
ESP_RETURN_ON_FALSE(s_initialized, ESP_ERR_INVALID_STATE, TAG,
"sensor hub not initialized");
// ... implementation
}
Use for:
- NULL pointer checks
- Range validation (0-100%, valid enum values)
- State validation (initialized, connected, ready)
- Buffer size checks
Pattern 4: Graceful Degradation
Handle non-critical component failures gracefully:
// In app_main.c
esp_err_t ret = data_logger_init(&logger_cfg);
if (ret == ESP_ERR_STORAGE_SD_NOT_PRESENT) {
ESP_LOGW(TAG, "SD card not present - using SPIFFS fallback");
s_status.sd_available = false;
// Continue without SD card
} else if (ret != ESP_OK) {
ESP_LOGE(TAG, "Data logger init failed: %s", esp_err_to_name(ret));
// Continue without data logging
}
// System continues with reduced functionality
Use for:
- SD card unavailable (use SPIFFS)
- WiFi unavailable (local-only mode)
- ML model unavailable (skip inference)
- Cloud service unavailable (local alerts only)
Pattern 5: NVS Special Handling
Handle NVS "not found" as normal condition for first boot:
nvs_handle_t handle;
esp_err_t ret = nvs_open("settings", NVS_READONLY, &handle);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to open NVS");
char ssid[33] = {0};
size_t len = sizeof(ssid);
ret = nvs_get_str(handle, "wifi_ssid", ssid, &len);
if (ret == ESP_ERR_NVS_NOT_FOUND) {
// First boot - no WiFi configured yet
ESP_LOGI(TAG, "No WiFi credentials - will show setup wizard");
nvs_close(handle);
return ESP_OK; // Not an error
} else if (ret != ESP_OK) {
// Actual error reading NVS
nvs_close(handle);
ESP_LOGE(TAG, "NVS read error: %s", esp_err_to_name(ret));
return ret;
}
nvs_close(handle);
Pattern 6: User-Actionable Errors
Log errors that require user action to the error log system:
#include "error_log.h"
// Storage full - user needs to clear history
if (ret == ESP_ERR_STORAGE_FULL) {
error_log_add(ERROR_CAT_STORAGE,
ESP_ERR_STORAGE_FULL,
"Storage full - history limited",
"Settings > Storage > Clear History");
}
// WiFi connection failed - user needs to check credentials
if (ret == ESP_ERR_WIFI_CONN) {
error_log_post_error(ERROR_CAT_WIFI,
ESP_ERR_WIFI_CONN,
"Failed to connect to WiFi",
"Check WiFi password and signal");
}
// SD card missing - insert SD card for full storage
if (ret == ESP_ERR_STORAGE_SD_NOT_PRESENT) {
error_log_add(ERROR_CAT_STORAGE,
ESP_ERR_STORAGE_SD_NOT_PRESENT,
"SD card not detected",
"Insert SD card for full history");
}
Effect:
- Shows toast notification on UI
- Appears in Settings > System > Errors screen
- Persisted to NVS across reboots (when NVS is healthy)
- Includes timestamp and suggested action
NVS Persistence Warning: If NVS persistence fails (e.g., NVS partition full or flash errors), the error log continues to function in RAM but errors may be lost on reboot. When this occurs:
- A warning is displayed in the System Health > Errors screen: "Error log persistence failed - errors may be lost on reboot"
- Status LED indicates critical state
- Use
error_log_get_status()to programmatically check persistence status
Pattern 7: Memory Allocation
Always check allocation results:
// PSRAM allocation for large buffers
void *buffer = heap_caps_malloc(size, MALLOC_CAP_SPIRAM);
if (buffer == NULL) {
ESP_LOGE(TAG, "Failed to allocate %zu bytes in PSRAM", size);
// Log detailed heap info
ESP_LOGE(TAG, "Free PSRAM: %zu bytes",
heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
ESP_LOGE(TAG, "Free internal: %zu bytes",
heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
return ESP_ERR_NO_MEM;
}
// LVGL allocations
lv_obj_t *label = lv_label_create(parent);
if (label == NULL) {
ESP_LOGE(TAG, "Failed to create LVGL label - heap full");
lv_mem_monitor_t mon;
lv_mem_monitor(&mon);
ESP_LOGE(TAG, "LVGL heap: %d%% free", mon.free_pct);
return; // Cannot create UI element
}
Error Logging Guidelines
Log Levels
| Level | Use When | Example |
|---|---|---|
ESP_LOGE() |
Operation failed, affects functionality | WiFi connection failed, SD card error |
ESP_LOGW() |
Unexpected but handled gracefully | NVS key not found (using default), weak WiFi signal |
ESP_LOGI() |
Normal operation events | Component initialized, connection established |
ESP_LOGD() |
Debug information (dev builds only) | Packet processing, cache statistics |
ESP_LOGV() |
Verbose trace (very detailed) | Ring buffer operations, state transitions |
Log Message Format
// Good: Specific, actionable
ESP_LOGE(TAG, "WiFi connection failed: %s (RSSI: %d dBm)",
esp_err_to_name(ret), rssi);
// Good: Includes context
ESP_LOGE(TAG, "Probe %016llX timeout - no response for %d seconds",
probe_id, timeout_sec);
// Bad: Vague, not helpful
ESP_LOGE(TAG, "Error occurred");
// Bad: Missing error details
ESP_LOGE(TAG, "WiFi failed");
Troubleshooting Guide
Common Error Patterns
Memory Errors
Symptom: ESP_ERR_NO_MEM, allocation failures, heap corruption
Causes:
- Heap exhausted (insufficient PSRAM or internal RAM)
- Memory leaks (allocated but never freed)
- LVGL heap full (frame buffers, widgets)
- Stack overflow (task stack too small)
Solutions:
# Check heap usage
esp_get_free_heap_size()
heap_caps_get_free_size(MALLOC_CAP_SPIRAM)
heap_caps_get_free_size(MALLOC_CAP_INTERNAL)
# Check LVGL heap
lv_mem_monitor_t mon;
lv_mem_monitor(&mon);
# Check stack usage
uxTaskGetStackHighWaterMark(task_handle)
# Enable heap tracing in menuconfig
Component Config → Heap Memory Debugging → Enable heap tracing
WiFi Connection Errors
Symptom: ESP_ERR_WIFI_CONN, ESP_ERR_WIFI_TIMEOUT, frequent disconnections
Causes:
- Wrong password (
ESP_ERR_WIFI_PASSWORD) - Network not found (
ESP_ERR_WIFI_SSID) - Weak signal (RSSI < -85 dBm)
- Router DHCP issues
- Interference (2.4GHz congestion)
Solutions:
- Check credentials in Settings > WiFi
- Move controller closer to router
- Check WiFi stats:
wifi_mgr_get_stats() - Enable verbose WiFi logs in menuconfig
- Try different WiFi channel on router
NVS Errors
Symptom: ESP_ERR_NVS_* errors, settings not saving
Causes:
- NVS partition full (
ESP_ERR_NVS_NO_FREE_PAGES) - NVS corrupted (
ESP_ERR_NVS_INVALID_STATE) - Encryption errors (production builds)
- Key too long (>15 chars)
Solutions:
# Erase NVS partition
idf.py erase-flash
# Or erase only NVS programmatically
nvs_flash_erase()
nvs_flash_init()
# Check NVS usage
nvs_get_stats(NULL, &stats)
Storage Errors
Symptom: ESP_ERR_STORAGE_* errors, history not saving
Causes:
- SD card removed (
ESP_ERR_STORAGE_SD_NOT_PRESENT) - SPIFFS full (
ESP_ERR_STORAGE_FULL) - Filesystem corrupted (
ESP_ERR_STORAGE_CORRUPT) - SD card format incompatible
Solutions:
- Insert SD card (FAT32 formatted)
- Clear history: Settings > Storage > Clear History
- Format SD card if corrupted
- Check storage stats on Settings > System screen
Thread Network Errors
Symptom: Probes not joining, RCP errors, network formation fails
Causes:
- RCP UART connection issue (GPIO 43/44)
- RCP firmware not flashed on nRF52840
- Thread dataset corruption
- Border router not started
- Interference (2.4GHz congestion)
Solutions:
- Check RCP UART wiring (TX=43, RX=44, RST=40)
- Reflash RCP firmware on nRF52840
- Reset Thread network: Settings > Thread > Factory Reset Thread
- Check Thread logs for Spinel errors
- Move probe closer to controller
Factory Reset Scenarios
| Error Pattern | Suggested Reset |
|---|---|
| Persistent NVS errors | Erase NVS only (Settings > System > Factory Reset) |
| WiFi always fails | Erase WiFi credentials only |
| Thread probes won't join | Reset Thread network only |
| System unstable after OTA | Rollback firmware (automatic on boot failure) |
| Complete system corruption | Full factory reset + reflash firmware |
API Reference
Error Logging Functions
error_log_init()
Initialize error log system (called in app_main).
esp_err_t error_log_init(void);
error_log_add()
Add error to persistent log with user action.
esp_err_t error_log_add(error_category_t category, uint16_t code,
const char *message, const char *action);
Parameters:
category: Error category (ERROR_CAT_*)code: Error-specific code (esp_err_t value)message: Human-readable message (max 63 chars)action: Suggested user action (max 47 chars, can be NULL)
Example:
error_log_add(ERROR_CAT_WIFI, ESP_ERR_WIFI_CONN,
"Failed to connect to WiFi",
"Check password in Settings > WiFi");
error_log_post_error()
Convenience function to post system error event (auto-logged).
esp_err_t error_log_post_error(error_category_t category, uint16_t code,
const char *message, const char *action);
error_log_get()
Retrieve error by index (0 = most recent).
esp_err_t error_log_get(uint8_t index, error_log_entry_t *entry);
error_log_count()
Get total number of errors in log.
uint8_t error_log_count(void);
error_log_unack_count()
Get number of unacknowledged errors (for badge display).
uint8_t error_log_unack_count(void);
error_log_ack_all()
Mark all errors as acknowledged.
esp_err_t error_log_ack_all(void);
error_log_clear()
Clear all errors from log.
esp_err_t error_log_clear(void);
error_log_get_status()
Get error log persistence status. Returns information about whether errors are being successfully saved to NVS.
esp_err_t error_log_get_status(error_log_status_t *status);
Parameters:
status: Pointer to status structure to fill
Returns:
ESP_OKon successESP_ERR_INVALID_STATEif error log not initializedESP_ERR_INVALID_ARGif status pointer is NULL
Status Structure:
typedef struct {
bool nvs_persistence_ok; /**< True if errors are being saved to NVS */
uint8_t entries_in_ram; /**< Count of entries in RAM */
} error_log_status_t;
Example:
error_log_status_t status;
if (error_log_get_status(&status) == ESP_OK) {
if (!status.nvs_persistence_ok) {
ESP_LOGW(TAG, "Error log persistence degraded - %d entries in RAM only",
status.entries_in_ram);
}
}
When nvs_persistence_ok is false:
- Errors are stored in RAM but may be lost on reboot
- UI displays warning in Settings > System > Errors screen
- Status LED indicates critical state
- Common causes: NVS partition full, NVS corruption, flash errors
Error Conversion
esp_err_to_name()
Convert standard ESP-IDF error code to string.
const char *esp_err_to_name(esp_err_t code);
Example:
ESP_LOGE(TAG, "Operation failed: %s", esp_err_to_name(ret));
// Output: "Operation failed: ESP_ERR_WIFI_CONN"
cleargrow_err_to_name()
Convert ClearGrow custom error code to string (includes storage errors).
const char *cleargrow_err_to_name(esp_err_t code);
Example:
ESP_LOGE(TAG, "Storage error: %s", cleargrow_err_to_name(ret));
// Output: "Storage error: ESP_ERR_STORAGE_SD_NOT_PRESENT"
Viewing Error Log
On Device
- Go to Settings > System > Diagnostics
- Tap Error Log
- Filter by category, date, or search text
- Tap error to see full details and suggested action
- Tap Clear All to clear error history
Serial Monitor
# View all logs
idf.py monitor
# Filter for errors only
idf.py monitor | grep -i "error\|fail"
# Save to file
idf.py monitor | tee error_log.txt
Coredump Analysis
If system panics, coredump is saved to flash partition:
# Analyze coredump
idf.py coredump-info
# Get detailed backtrace
idf.py coredump-debug
Error Log Format
[2025-12-09 14:32:15] ERROR | WIFI | ESP_ERR_WIFI_CONN (0x3007)
Message: Failed to connect to WiFi network "MyNetwork"
Action: Check WiFi password in Settings > WiFi
Stack: wifi_manager.c:342 -> wifi_event_handler
References
- ESP-IDF Error Handling Guide: https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-guides/error-handling.html
- ESP-IDF API Error Codes: https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-reference/error-codes.html
- ClearGrow Error Log Component:
/opt/repos/controller/components/common/include/error_log.h - ClearGrow Error Codes Header:
/opt/repos/controller/components/common/include/error_codes.h - Storage Error Codes:
/opt/repos/controller/components/storage/include/storage_types.h