How to catch a backend yaml error and notify

using a custom component in a yaml config, on user error, I get this in the HA log

2026-04-25 10:08:48.346 ERROR (SyncWorker_16) [annotatedyaml.loader] found duplicate anchor 'styles'; first occurrence
in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 24, column 15
second occurrence
in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 51, column 13

now we can trigger an automation on the ERROR with

    triggers:
      trigger: event
      event_type: system_log_event
      event_data:
        level: ERROR

but id need the trigger to be more specific and catch it only when the annotatedyaml.loader is the logger and id like the reason itself to be in the notification so smthg like

error in annotatedyaml.loader:

error: found duplicate anchor ‘styles’;

etc

how can we catch that best

testing reveals:

event_type: system_log_event
data:
  name: custom_components.uix.helpers
  message:
    - >-
      Failed to parse foundry file:
      /config/dashboard/uix_foundries/uix_foundries.yaml
  level: ERROR
  source:
    - custom_components/uix/helpers.py
    - 135
  timestamp: 1777112529.2561834
  exception: >-
    Traceback (most recent call last):
      File "/usr/local/lib/python3.14/site-packages/annotatedyaml/loader.py", line 201, in parse_yaml
        return _parse_yaml(FastSafeLoader, content, secrets)
      File "/usr/local/lib/python3.14/site-packages/annotatedyaml/loader.py", line 228, in _parse_yaml
        return yaml.load(content, Loader=lambda stream: loader(stream, secrets))  # type: ignore[arg-type]  # noqa: S506
               ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.14/site-packages/yaml/__init__.py", line 81, in load
        return loader.get_single_data()
               ~~~~~~~~~~~~~~~~~~~~~~^^
      File "/usr/local/lib/python3.14/site-packages/yaml/constructor.py", line 49, in get_single_data
        node = self.get_single_node()
      File "yaml/_yaml.pyx", line 674, in yaml._yaml.CParser.get_single_node
      File "yaml/_yaml.pyx", line 688, in yaml._yaml.CParser._compose_document
      File "yaml/_yaml.pyx", line 732, in yaml._yaml.CParser._compose_node
      File "yaml/_yaml.pyx", line 846, in yaml._yaml.CParser._compose_mapping_node
      File "yaml/_yaml.pyx", line 732, in yaml._yaml.CParser._compose_node
      File "yaml/_yaml.pyx", line 846, in yaml._yaml.CParser._compose_mapping_node
      File "yaml/_yaml.pyx", line 732, in yaml._yaml.CParser._compose_node
      File "yaml/_yaml.pyx", line 846, in yaml._yaml.CParser._compose_mapping_node
      File "yaml/_yaml.pyx", line 732, in yaml._yaml.CParser._compose_node
      File "yaml/_yaml.pyx", line 846, in yaml._yaml.CParser._compose_mapping_node
      File "yaml/_yaml.pyx", line 732, in yaml._yaml.CParser._compose_node
      File "yaml/_yaml.pyx", line 846, in yaml._yaml.CParser._compose_mapping_node
      File "yaml/_yaml.pyx", line 724, in yaml._yaml.CParser._compose_node
    yaml.composer.ComposerError: found duplicate anchor; first occurrence
      in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 24, column 15
    second occurrence
      in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 51, column 13

    During handling of the above exception, another exception occurred:


    Traceback (most recent call last):
      File "/usr/local/lib/python3.14/site-packages/annotatedyaml/loader.py", line 216, in _parse_yaml_python
        return _parse_yaml(PythonSafeLoader, content, secrets)
      File "/usr/local/lib/python3.14/site-packages/annotatedyaml/loader.py", line 228, in _parse_yaml
        return yaml.load(content, Loader=lambda stream: loader(stream, secrets))  # type: ignore[arg-type]  # noqa: S506
               ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.14/site-packages/yaml/__init__.py", line 81, in load
        return loader.get_single_data()
               ~~~~~~~~~~~~~~~~~~~~~~^^
      File "/usr/local/lib/python3.14/site-packages/yaml/constructor.py", line 49, in get_single_data
        node = self.get_single_node()
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 36, in get_single_node
        document = self.compose_document()
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 55, in compose_document
        node = self.compose_node(None, None)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 84, in compose_node
        node = self.compose_mapping_node(anchor)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 133, in compose_mapping_node
        item_value = self.compose_node(node, item_key)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 84, in compose_node
        node = self.compose_mapping_node(anchor)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 133, in compose_mapping_node
        item_value = self.compose_node(node, item_key)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 84, in compose_node
        node = self.compose_mapping_node(anchor)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 133, in compose_mapping_node
        item_value = self.compose_node(node, item_key)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 84, in compose_node
        node = self.compose_mapping_node(anchor)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 133, in compose_mapping_node
        item_value = self.compose_node(node, item_key)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 84, in compose_node
        node = self.compose_mapping_node(anchor)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 133, in compose_mapping_node
        item_value = self.compose_node(node, item_key)
      File "/usr/local/lib/python3.14/site-packages/yaml/composer.py", line 75, in compose_node
        raise ComposerError("found duplicate anchor %r; first occurrence"
                % anchor, self.anchors[anchor].start_mark,
                "second occurrence", event.start_mark)
    yaml.composer.ComposerError: found duplicate anchor 'styles'; first
    occurrence
      in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 24, column 15
    second occurrence
      in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 51, column 13

    The above exception was the direct cause of the following exception:


    Traceback (most recent call last):
      File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 77, in parse_yaml
        return parse_annotated_yaml(content, secrets)
      File "/usr/local/lib/python3.14/site-packages/annotatedyaml/loader.py", line 208, in parse_yaml
        return _parse_yaml_python(content, secrets)
      File "/usr/local/lib/python3.14/site-packages/annotatedyaml/loader.py", line 219, in _parse_yaml_python
        raise YAMLException(exc) from exc
    annotatedyaml.exceptions.YAMLException: found duplicate anchor 'styles';
    first occurrence
      in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 24, column 15
    second occurrence
      in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 51, column 13

    The above exception was the direct cause of the following exception:


    Traceback (most recent call last):
      File "/config/custom_components/uix/helpers.py", line 135, in load_foundries_from_files
        content = parse_yaml(fp, secrets)
      File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 79, in parse_yaml
        raise HomeAssistantError(str(exc)) from exc
    homeassistant.exceptions.HomeAssistantError: found duplicate anchor
    'styles'; first occurrence
      in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 24, column 15
    second occurrence
      in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 51, column 13
  count: 1
  first_occurred: 1777112529.2561834
origin: LOCAL
time_fired: "2026-04-25T10:22:09.425282+00:00"
context:
  id: 01KQ22JEGHG6W33R3CMN7E56XK
  parent_id: null
  user_id: null

event_type: system_log_event
data:
  name: annotatedyaml.loader
  message:
    - |-
      found duplicate anchor 'styles'; first occurrence
        in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 24, column 15
      second occurrence
        in "/config/dashboard/uix_foundries/uix_foundries.yaml", line 51, column 13
  level: ERROR
  source:
    - util/yaml/loader.py
    - 77
  timestamp: 1777112529.249408
  exception: ""
  count: 1
  first_occurred: 1777112529.249408
origin: LOCAL
time_fired: "2026-04-25T10:22:09.345272+00:00"
context:
  id: 01KQ22JEE1H6Z4YCWH17W53TD0
  parent_id: null
  user_id: null

so that would be enough to set the automation trigger, and create a useful notification…
unfortunately those are not in the 1 single event, so my challenge lies in combining this

ok this works, and is rather easy and straightforward.

automation:

  - id: alert_yaml_error
    max_exceeded: silent
    triggers:
      trigger: event
      event_type: system_log_event
      event_data:
        name: annotatedyaml.loader
    actions:
      - variables:
          message: >
            {{trigger.event.data.message}}
      - action: persistent_notification.create
        data:
          title: '{{trigger.event.data.name}}'
          message: '{{message}}'

so even while the Yaml checker on /developer-tools/yaml doesnt check this syntax for custom integrations, the automation catches it because of the system log event.

next step: create a toast :wink:

document.querySelector("home-assistant").dispatchEvent(new CustomEvent("hass-notification", { detail: { message: "User made a YAML error", duration: -1, dismissable: true }, bubbles: true, composed: true }));

1 Like

ok settling for this

automation:

  - id: alert_yaml_error
    max_exceeded: silent
    triggers:
      trigger: event
      event_type: system_log_event
      event_data:
        name: annotatedyaml.loader
    actions:
      - variables:
          message: >
            {{trigger.event.data.message}}
          name: '{{trigger.event.data.name}}'
      - action: persistent_notification.create
        data:
          title: '{{name}}'
          message: '{{message}}'
      - action: browser_mod.javascript
        data:
          code: |
            document.querySelector("home-assistant").dispatchEvent(
              new CustomEvent("hass-notification", {
                detail: {
                  message: "{{ (name ~ ': ' ~ message) | replace('"', '\\"') }}",
                  duration: -1,
                  dismissable: true
                },
                bubbles: true,
                composed: true
              })
            );

and styling in theme for that particular toast dialog

  uix-toast-yaml: |
    .: |
      {% if "UIX has been updated" in params.message %}
      ha-button {
        --wa-color-on-normal: green;
      }
      {% endif %}
    $: |
      {% if "UIX has been updated" in params.message %}
      div.toast {
        background: var(--alert-color);
        color: white;
        animation: blink ease 2s infinite;
        box-shadow: var(--box-shadow);
        border: 3px white double;
      }
      {% elif "annotatedyaml.loader" in params.message %}
      div.toast {
        background: var(--warning-color);
        color: var(--success-color);
        animation: glow ease 2s infinite;
        box-shadow: var(--box-shadow);
        border: 3px var(--success-color) double;
      }
      {% endif %}
      @keyframes blink {
        50% {opacity: 0.2;}
      }
      @keyframes glow {
        0% {
          box-shadow: 0 0 0px var(--warning-color);
        }
        50% {
          box-shadow: 0 0 4px 2px var(--success-color);
        }
        100% {
          box-shadow: 0 0 0px var(--warning-color);
        }
      }
    

Apr-26-2026 14-08-35

only possible with UIX Styling entities, badges, elements and entity markers - UI eXtension and Themes - UI eXtension

O, and browser_mod for the action

I think the ‘blink’ keyframe might be in the wrong expression block.

Nope it’s alright .

But also not used in this animation for the yaml

Right, but it is used in the animation: for “UIX has been updated” but it’s buried on the other side of elif. How can it access the keyframe then?

Wait , I see what you mean.

It’s a c&p typo

In my full theme it’s not there at all and declared in a totally different spot

I pasted it in here after posting the if then else…
It’s difficult to use this community editor on mobile.

Let me fix it.
Thx for your eyes…

edited once more, and now use a bit better contrasting colors.Moved it to this complete section in my themes now also, so we’re not confused going forward…:

  uix-toast-yaml: |
    .: |
      {% if "UIX has been updated" in params.message %}
      ha-button {
        --wa-color-on-normal: green;
      }
      {% endif %}
    $: |
      {% if "UIX has been updated" in params.message %}
        div.toast {
          background: var(--alert-color);
          color: white;
          animation: blink ease 2s infinite;
          box-shadow: var(--box-shadow);
          border: 3px white double;
        }
      {% elif "annotatedyaml.loader" in params.message %}
        div.toast {
          background: var(--warning-color);
          color: black;
          animation: blink ease 2s infinite;
          box-shadow: var(--box-shadow);
          border: 3px var(--success-color) double;
        }
      {% endif %}
      @keyframes blink {
        50% {opacity: 0.4;}
      }
      @keyframes glow {
        0% {
          box-shadow: 0 0 0px var(--warning-color);
        }
        50% {
          box-shadow: 0 0 4px 2px var(--success-color);
        }
        100% {
          box-shadow: 0 0 0px var(--warning-color);
        }
      }
1 Like