From 80555fad02ead800154bdcf93d63ef72e60ee65f Mon Sep 17 00:00:00 2001 From: Johannes Krobath Date: Thu, 9 Jul 2026 22:16:49 +0200 Subject: [PATCH] fix: ignore_device_delete crashed on device leave and never matched insertedDeviceLeave is the spliced deviceLeave listener that is armed at every controller start. As soon as any device or model has the 'ignore Delete' option set (that is the optionExists gate), the next deviceLeave for a resolvable device threw: - entity.model does not exist on any resolveEntity() return shape (device/group/coordinator all return {type, device, mapped, ...}), so entity.model.modelID is a TypeError inside an async event listener - an unhandled rejection instead of an ignored leave. Independently, the option lookup itself could never match: getDeviceOption(device_id, model_id, option, dOnly) was called with 3 arguments, so it looked up the option key `false` and returned undefined - the leave was never ignored even without the crash. Now the option is read as getDeviceOption(ieee, entity.mapped?.model, 'ignore_device_delete', true), which resolves the per-device option and the per-model option (the option is declared byDevice and byModel), and the log prints the existing entity.device.modelID. Co-Authored-By: Claude Fable 5 --- lib/zigbeecontroller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/zigbeecontroller.js b/lib/zigbeecontroller.js index 24d5d12c..5531abdb 100644 --- a/lib/zigbeecontroller.js +++ b/lib/zigbeecontroller.js @@ -1061,8 +1061,8 @@ class ZigbeeController extends EventEmitter { if (this.localConfig.optionExists('ignore_device_delete')) { const entity = await this.resolveEntity(message.device || message.ieeeAddr); if (entity) { - if ((this.localConfig.getDeviceOption(entity.device.ieeeAddr, entity.model.modelID, false) ?? {}).ignore_device_delete) { - this.warn(`Ignoring device_leave message from '${this.devLabel(message.ieeeAddr)}' (${entity.model.modelID})`); + if (this.localConfig.getDeviceOption(entity.device.ieeeAddr, entity.mapped?.model, 'ignore_device_delete', true)) { + this.warn(`Ignoring device_leave message from '${this.devLabel(message.ieeeAddr)}' (${entity.device.modelID})`); return; } }