Your Home Assistant automation UI shows a red “Not triggered” label. You open the logbook and the same automation shows an entry that says it ran, changed states, and completed. Both are technically correct, and figuring out which is misleading you takes an understanding of Home Assistant’s two automation modes that the docs cover but do not emphasize. This guide unpacks the state-versus-event distinction, why it produces contradictory UI readings, and how to make automations report their actual behavior honestly.
The two modes and why they look identical in YAML
Every Home Assistant automation has a trigger. The trigger can be one of about 14 types, and two of them look almost identical:
trigger: state— fires when an entity’s state matches a conditiontrigger: numeric_state— fires when a numeric attribute crosses a threshold
But the runtime treats these very differently from event-based triggers like event, time_pattern, and webhook. State-based triggers only fire when the trigger’s condition transitions from false to true. Event-based triggers fire whenever the event happens, regardless of state.
The UI’s “Not triggered” indicator reads from the automation’s own trace log, which records only successful, condition-passing runs. The logbook reads from Home Assistant’s global event bus, which records every entity change the automation caused. If your automation’s action is called by another automation (indirect trigger), the logbook shows it running while the trigger log correctly shows it did not directly fire.
The five common reasons the UI shows “Not triggered” while things clearly changed
- The automation was called by service invocation, not its own trigger. Another automation ran
service: automation.triggertargeting this one, which bypasses the trigger evaluation. - The trigger fired but a condition blocked the action. “Not triggered” in the UI is misleading here; it should say “triggered but condition failed.” Home Assistant reserves “triggered” for the trigger AND conditions passing.
- Restart mode caused the previous run to be canceled. If mode is
restartand the trigger fires twice in quick succession, the first run’s trace is discarded. - Trigger uses a template that returns the same value it did last time. State triggers require a transition; if the template evaluated to true both this second and the last, no transition happened.
- The trigger’s entity has been unavailable, then came back online with the trigger condition already met. Home Assistant treats coming-back-from-unavailable as one transition, and if the entity was already in the trigger state at the moment it became available, some setups do not register the transition.
Reading the trace to know for sure
Every automation in Home Assistant stores its last 5 traces by default (configurable up to 50 in automation.yaml with the trace key). Open Settings, Automations, click the automation, then the three-dot menu, then Traces. You get a visual graph showing:
- Green nodes: passed
- Red nodes: blocked
- Grey nodes: skipped
The trigger node at the top tells you exactly which trigger fired (if you have multiple) and what its state was. The condition nodes below show which passed and which blocked. If the trace is empty or missing, the run never entered this automation, meaning something called its action directly.
Diagnostic sequence: state versus event confusion
| Symptom | Likely cause | Fix |
|---|---|---|
| UI red “Not triggered,” logbook shows changes | Action called by another automation | Add a state trigger that also matches, or accept that this automation’s action is being reused |
| UI green triggered, but action did not visibly change anything | Condition blocked, or action succeeded silently | Read the trace, check the last action node’s result |
| Automation fires reliably at 8 AM but not at 8 AM on the day DST changes | Time-based trigger runs on wall-clock, DST shifts local time | Use time_pattern with UTC offset, or accept the one-day skip |
| Trigger fires every entity update, not only on state change | You used trigger: event instead of trigger: state |
Change to state trigger with a from/to constraint |
| Trigger stopped working after Home Assistant restart | Trigger references an integration that loads asynchronously | Add a trigger.platform: homeassistant, event: start as a re-arm step, or use MQTT-based state instead |
The pattern that traps most people
Motion sensor turns off lights. The automation is set to trigger when binary_sensor.hallway_motion goes to “off” for 5 minutes. Owners report the automation intermittently fails to fire even though the sensor clearly did go off.
What is actually happening: the for: 5 minutes qualifier requires the state to remain “off” continuously for 5 minutes. If the sensor briefly reports “unavailable” during that window (which most Zigbee motion sensors do every 5 to 10 minutes as they check in), the timer resets. So the trigger only fires when the sensor stays cleanly in the “off” state for a full 5 minutes with no interruption.
The fix is either a template trigger that treats “unavailable” as “off,” or a template that uses as_timestamp(now()) - as_timestamp(states.binary_sensor.hallway_motion.last_changed) > 300, which does not care about intermediate unavailable states.
Frequently asked questions
Why is the trace empty but the logbook says the automation ran? The automation’s action was called by another automation via service: automation.trigger. That bypasses the trigger evaluation, so no trace is created, but the actions still run and log.
Can I keep more than 5 traces per automation? Yes. In your automation’s YAML, add trace: stored_traces: 50 at the top level. The default is 5 to save memory.
Do UI-created automations trace differently than YAML ones? No. UI automations are stored as YAML under the hood in automations.yaml and behave identically.
What is the difference between single, restart, queued, and parallel mode? Single ignores new triggers if one is running. Restart cancels the previous run and starts new. Queued runs one at a time in FIFO order. Parallel runs concurrent instances. For most home automations, restart is the safest default.
Does using MQTT triggers avoid this confusion? Partly. MQTT triggers are event-based and fire on every published message, so they do not have the state-transition trap. But they can fire more often than you want, so you may need a condition to filter.