I make a diagnostic with Claude (AI) in case of he find something he delivery me this diagnostic not sure is correct but can be a first investigation:
Diagnosis
The restart chain involves two separate bugs across two different repos:
Bug 1 — websocket_server.cpp (the REST plugin)
The onSocketDisconnected() function has an iterator corruption bug. After doing a swap-and-pop removal, the for loop increments i, silently skipping the moved element. In the worst case (with multiple clients or rapid reconnects), this leaves a dangling pointer in the clients vector:
// Current (buggy) code
void WebSocketServer::onSocketDisconnected()
{
for (size_t i = 0; i < clients.size(); i++)
{
QWebSocket *sock = qobject_cast<QWebSocket*>(sender());
if (sock && clients[i] == sock)
{
sock->deleteLater();
clients[i] = clients.back(); // ← moves last element to slot i
clients.pop_back(); // ← removes the duplicate at the back
// ❌ NO break/i-- here: the loop increments i, skipping slot i
}
}
}
The same bug exists in onSocketError() . The fix is simple — add a break since a disconnected signal maps to exactly one socket:
// Fixed
void WebSocketServer::onSocketDisconnected()
{
QWebSocket *sock = qobject_cast<QWebSocket*>(sender());
DBG_Assert(sock);
for (size_t i = 0; i < clients.size(); i++)
{
if (clients[i] == sock)
{
sock->deleteLater();
clients[i] = clients.back();
clients.pop_back();
break; // ✅ exit immediately — one signal = one socket
}
}
}
Apply the same fix to onSocketError()
Bug 2 — HTTP server timeout (the deconz core, v2.32.2+)
The commit a2a8e2c in the deconz core repo rewrote the HTTP server and introduced a timeout condition that incorrectly fires on idle connections (not just timed-out ones). When HA restarts and closes its HTTP connection, the server hits this condition and triggers a full process restart via restartAppTimerFired(). This was partially fixed in v2.32.4 (de2c3f: “Fix Websockets being closed after timeout due wrong condition”), but the crash path through the HTTP layer remains in v2.32.5.