From c133f44d28cbd1a8670ad06e0753f9bf8334f238 Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Thu, 30 Jul 2026 12:30:23 +0200 Subject: [PATCH] docs(zigbee2mqtt): correct the network_key extraction comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review point on #444, which merged before this could be folded in. The comment claimed the listed shapes yield "null" at rc=0. That describes BARE `.network_key.key`, not the expression actually written, and it contradicted its own closing line two lines below. Measured against jq 1.7.1 in the image, `(.network_key?.key? // "")` returns an EMPTY string at rc=0 for all of: {} {"devices":[]} {"network_key":{}} {"network_key":null} {"network_key":"abc"} {"network_key":123} [] "a string" and never the literal text null, because `// ""` maps a null result to empty. Bare `.network_key.key` is what exits 5 on the last four shapes. Checking that also turned up something the review did not mention: because KEY can never be "null" with the current expression, the `[ "$KEY" = "null" ]` arm is dead code today. Kept deliberately as belt-and-braces for a future edit that drops the `// ""` fallback, and now labelled as such rather than left looking like the arm that fires. Comment-only: `git diff` shows zero changed lines outside comments, and the rendered script is unchanged in behaviour. NOTE: this text lives in the Deployment's init container command, so it is part of the pod template — merging rolls the zigbee2mqtt pod (~20s of Zigbee downtime, replicas: 1 + Recreate). Incidental benefit: the restart resets Z2M's in-memory configure attempt counter, giving the Philips devices that are interviewed but not yet bound (both RDM001 Treppenhaus switches, the RWL022, and Sarah) three fresh configure attempts. Co-Authored-By: Claude Opus 5 (1M context) --- .../zigbee2mqtt-deployment.yaml | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml b/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml index 27d8bfba..b5e06ee4 100644 --- a/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml +++ b/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml @@ -77,22 +77,29 @@ spec: # key, because "devices" sorts before "network_key". An unanchored # extraction yields a device link key, and herdsman then forms a # NEW network and drops every device. - # `?` on BOTH selectors, so every malformed shape reaches the checks - # below with a readable message instead of aborting on jq's raw - # error under `set -e`. Verified against jq 1.7.1 in this image: - # {"devices":[]} / {"network_key":{}} / {"network_key":null} - # -> "null", rc=0 (missing path is lenient) - # {"network_key":"abc"} / {"network_key":123} - # -> rc=5 without `?` on .key - # [] / "a string" -> rc=5 without `?` on .network_key too, - # since the top level is not an object - # `.network_key?.key?` returns empty for all of them at rc=0. + # `?` on BOTH selectors, plus the `// ""` fallback, so every + # malformed shape reaches the checks below with a readable message + # instead of aborting on jq's raw error under `set -e`. + # + # Measured against jq 1.7.1 in this image. The expression AS WRITTEN + # returns an EMPTY string at rc=0 for every one of: + # {} {"devices":[]} {"network_key":{}} {"network_key":null} + # {"network_key":"abc"} {"network_key":123} (parent not an object) + # [] "a string" (top level not an object) + # and the key itself for a well-formed backup. + # + # The guards are what make that true. Bare `.network_key.key` exits + # 5 with `Cannot index ... with string "key"` on the last four + # shapes, and `set -e` would abort right here, surfacing jq's error + # instead of the FATAL lines below. KEY=$(jq -r '(.network_key?.key? // "")' /backup/coordinator_backup.json) # Fail LOUDLY rather than render a wrong key, for the same reason. - # "null" is what jq prints when the path resolves to null, empty is - # what `?` yields for a malformed shape — treat both as absent, - # rather than letting them be reported as merely "non-hex", which - # sends you looking at the key instead of at the field. + # `-z` is the arm that actually fires today: `// ""` maps a null + # result to empty, so KEY is never the literal text "null" with the + # expression above. The "null" arm is belt-and-braces for a future + # edit that drops the fallback, where jq WOULD print `null`. Both + # mean "absent" — reporting them as merely "non-hex" would send you + # looking at the key instead of at the missing field. if [ "$KEY" = "null" ] || [ -z "$KEY" ]; then echo "FATAL: .network_key.key absent from coordinator_backup.json" >&2 exit 1 -- 2.54.0