payload_not_jsonThe message body isn't valid JSON. Common cause: single quotes instead of double quotes, or a trailing comma.
GardenSpine.h prevents this. Download a clean copy if the helper was edited. Only a custom publisher needs to inspect its JSON punctuation.
missing_fieldYour JSON is missing unit. All five fields are required — see the spec.
GardenSpine.h supplies all five fields. Restore the helper if it was edited; custom publishers should compare their output with the five labeled fields on the spec.
device_id_mismatchThe topic says gm-02 but the payload says gm-01. They must match — you probably copied the config from another node.
GardenSpine.h uses one config value in both places. Check SPINE_DEVICE_ID in config.h, then restore the helper if the IDs still differ.
unit_mismatchYou sent unit: "C" but temperature expects celsius. Units are spelled out.
Copy the unit from the registry. Unit names are lowercase contract values, not display abbreviations.
value_type_wrongvalue should be a number for temperature, but arrived as text. Drop the quotes.
Pass the sensor number directly to spine.publish(). Do not turn it into text first.
value_out_of_range1284 °C is outside the plausible range. Raw sensor value instead of a converted one?
Print the raw sensor value and the converted value separately. Confirm the sensor library and conversion formula.
timestamp_unparseablets must be ISO 8601 UTC like 2026-08-14T09:32:00Z, or null if your device has no clock. null is fine.
GardenSpine.h sends null and lets the broker stamp arrival time. Restore the helper if a device timestamp appears unexpectedly.
topic_malformedTopic needs five segments: garden/zone/device-type/device-id/measurement.
GardenSpine.h builds the topic. Check the zone, device type, and device ID in config.h instead of typing a topic.
zone_not_registeredZone greenhous-1 isn't in the registry — check the spelling, or open a PR to add it.
Copy SPINE_ZONE from the registry into config.h. If the physical location is genuinely new, ask for a registry change.
device_type_not_registeredThis device type is not registered. Copy it from your charter configuration.
Copy SPINE_DEVICE_TYPE from the assigned charter. Do not invent a type in config.h.
device_not_registeredThis device ID is not registered. Copy it from the credential slip.
Copy the full device ID and MQTT username from the credential slip. Ask an organiser if the device is absent from the registry.
device_registration_mismatchThe topic's zone or device type does not match this device's registry entry.
Use the zone and device type printed in the assigned charter. A valid device ID cannot move to another topic branch without a registry change.
unexpected_fieldThe payload has a field outside the five-field contract. Remove the extra field.
The canonical payload contains exactly five fields. Restore GardenSpine.h or remove the extra key from a custom publisher.
rate_limitedThis device published more than 60 messages in a minute and is being throttled. Slow your loop down.
Publish measurements once per minute while debugging. Check that the publish call is not inside a loop without a delay.