Our Cloudron event log unexpectedly showed "30 Jul 2026, 01:00 boot Cloudron started with version 9.1.6" this morning, which appears to have made our overnight backup fail, so I was looking into what happened. We are on British Summer Time, so this actually happened at 00:00 UTC.
The /home/yellowtent/platfromdata/logs/box.log shows the following at this time:
2026-07-29T23:59:53.169Z apphealthmonitor: app health: 17 running / 4 stopped / 1 unresponsive
2026-07-30T00:00:00.005Z janitor: Cleaning up docker volumes
2026-07-30T00:00:00.009Z janitor: Cleaning up expired tokens
2026-07-30T00:00:00.011Z eventlog: cleanup: pruning events. creationTime: Fri May 01 2026 00:00:00 GMT+0000 (Coordinated Universal Time)
2026-07-30T00:00:00.017Z janitor: Cleaned up 0 expired tokens
2026-07-30T00:00:00.322Z From uncaughtException handler.
2026-07-30T00:00:00.322Z TypeError: Cannot read properties of undefined (reading 'id')
2026-07-30T00:00:00.322Z at Object.upsertLoginEvent (file:///home/yellowtent/box/src/eventlog.js:57:58)
2026-07-30T00:00:00.322Z at process.processTicksAndRejections (node:internal/process/task_queues:103:5)
2026-07-30T00:00:24.846Z server: ==========================================
2026-07-30T00:00:24.856Z tasks: stopAllTasks: 0 tasks are running. sending abort signal
2026-07-30T00:00:24.858Z shell: tasks: /usr/bin/sudo --non-interactive /home/yellowtent/box/src/scripts/stoptask.sh all
2026-07-30T00:00:24.850Z server: Cloudron 9.1.6
I believe this is the code line in eventlog.js where .id was put on something that was undefined?:
async function upsertLoginEvent(action, source, data) {
assert.strictEqual(typeof action, 'string');
assert.strictEqual(typeof source, 'object'); // an AuditSource
assert.strictEqual(typeof data, 'object');
// can't do a real sql upsert, for frequent eventlog entries we only have to do 2 queries once a day
const queries = [{
query: 'UPDATE eventlog SET creationTime=NOW(), dataJson=? WHERE action = ? AND sourceJson LIKE ? AND DATE(creationTime)=CURDATE()',
args: [ JSON.stringify(data), action, JSON.stringify(source) ]
}, {
query: 'SELECT ' + EVENTLOG_FIELDS + ' FROM eventlog WHERE action = ? AND sourceJson LIKE ? AND DATE(creationTime)=CURDATE()',
args: [ action, JSON.stringify(source) ]
}];
const result = await database.transaction(queries);
if (result[0].affectedRows >= 1) return result[1][0].id; // <--- JUST HERE!
// no existing eventlog found, create one
return await add(action, source, data);
}
ChatGPT is telling me that the code is operating on the eventlog table at the exact moment the cleanup job is pruning that same table, but you might have more idea what is actually happening?
The event log showed a user logged into their mailbox at 00:59 (or 23:59 UTC) just before this happened, but don't know if that is related or not. In any case, I hope that is helpful in catching a possible error.
Best wishes,
Dave.