Templates: how to avoid triggering without a unique ID?

Here's a button that does not include a unique_id.

This is just a quick button to click on a dashboard that something else triggers off of.

template:
  - button:
      - name: Test Button
        default_entity_id: button.test_button
        press:
          - stop: done

Without the unique_id there doesn't seem to be a way to NOT trigger when templates are reloaded. (With the unique_id you can look for the "unavailable" state.)

The events have to_state: null and from_state: null.

I tried the usual suspects "unknown", "null", "None", "unavailable" and even the "~' yaml trick.

Is there another method I'm not seeing? I didn't see this mentioned in the documentation.

I think you need to back up and explain what you are trying to do...

There are a number of cards that don't require an entity and allow card actions such as firing a script. If you don't need the entity, why create it?

If you just want an entity and this is an issue, why not assign it a unique_id?

Or, why not just use a Input button helper? A Template Button's main purpose is that it combines features of an Input Button and an automation. If you aren't utilizing the "automation" portion represented by the press action sequence, then the Template Button offers no benefit over the Input Button.

Because the question was if there's no unique_id is there a way to block the trigger. That's all. Just curious if there was a reason and if it was a documented state.

And for the questions you asked:

Template buttons have an availability config option which can be also checked by uix.

I'm not using automations, I'm using triggered templates.

I have a vague recollection of a thread about this more than a year ago... but I don't remember what the answer was.

A trigger's a trigger... have you considered just using a custom event?

A bit off topic, but the button is triggering (yes, by a state event) a template sensor that is updating its state and attributes, which needs to be done in a template sensor.

Your problem is that you are testing if the value of a key is null.
In you head it should look like this:
{ Key : NULL }

The likely fact is that the key do not even exist, so the it is in fact this
{ }

You need to test if the key exist rather than what the value of the key is.

The trigger is a dictionary and the key is there, just no object attached. And the value is thus NoneType.

It's just a side effect of not setting unique_id, which results in the typical use of the not_to and not_from tests not working on the trigger during a reload because, well, there's no attached State object to test the state of.

Sure, one could test this is a condition, if that's what you are implying. But the not_to and not_from are the typical way of blocking triggers.

I was just reloading templates frequently and kept seeing (unrelated) logs for a button push, an edge case I was curious about.

template buttons do not update from the template integration FYI. There is no "templates" that cause buttons to resolve a new state. This is normal button entity behavior.

Interesting about the template buttons, but this isn't specific to buttons.

Again, only happens on YAML reload and can simply add a unique_id, so not a big issue at all. unique_id is optional, but there's this difference in behavior.

But to make it clear:

The point is if you do not set a unique_id then when reloading you get a null for the state object (it's triggered twice -- unloading and loading).

So, with this sensor (no unique_id)

  - sensor:
      - name: Test Standard Template
        default_entity_id: sensor.std_template
        state: "{{ states('input_text.some_input_text') }}"

The trigger will look like the following. Note how the from_state is missing an object.

trigger:
  id: '0'
  idx: '0'
  alias: null
  platform: state
  entity_id: sensor.std_template
  from_state: null
  to_state:
    entity_id: sensor.std_template
    state: Some text

Without a from_state object you cannot use not_from: unavailable to block that trigger as there's no state object to inspect. (I'm a bit surprised there's no error in the logs.)

There's two events, so the other event is to_state: null so checking not_to: unavailable fails as well.

Once there's an unique_id both state objects are there, so testing for unavailable works.

trigger:
  id: '0'
  idx: '0'
  alias: null
  platform: state
  entity_id: sensor.std_template_with_id
  from_state:
    entity_id: sensor.std_template_with_id
    state: unavailable
    attributes:
      restored: true
      friendly_name: Test Standard Template With ID
      supported_features: 0
    last_changed: '2026-06-30T17:13:01.277387+00:00'
    last_reported: '2026-06-30T17:13:01.277387+00:00'
    last_updated: '2026-06-30T17:13:01.277387+00:00'
    context:
      id: 01KWCRA6JX7VGDTFEQJHMGWCZP
      parent_id: null
      user_id: null
  to_state:
    entity_id: sensor.std_template_with_id
    state: Some text

I've been using this for years to avoid that


  - condition: template
    value_template: "{{ trigger | default(none) is not none and trigger.to_state is defined and trigger.from_state is defined }}"

you can find references to this all over the forums when yaml entities were the only thing you had. (yaml entities == no unique_id)

But you'll have to find old posts before the UI and config entry existed. Circa 2015-2019ish.