Skip to content

When YAML Fails: Find the Error Without Guessing

13/11/2026
Troubleshooting YAML errors in Home Assistant

This article may contain affiliate links. If you buy through these links, the price is the same for you and the store pays me a small commission that helps keep Tecnoyfoto running.

← Chapter 10 · Course index

An automation can fail because a space is missing, a key is in the wrong place, an entity does not exist, or the logic prevents an action from being reached. All four problems feel the same—”it doesn’t work”—but they are not investigated with the same tool.

In this chapter, we will build a troubleshooting method. It will not be a collection of error messages to memorize, because messages change and no list can cover every combination. We will learn to identify the layer where the failure occurs, gather evidence, and change one thing at a time.

The sequence will always be:

observe → read → classify → formulate a hypothesis
         → change one thing → validate → reproduce → check

Start by describing the problem accurately

“The automation isn’t working” does not tell us what happened. Before editing anything, answer questions based on observable facts:

  • Does Home Assistant accept and load the configuration?
  • Is the automation enabled in the user interface?
  • Is a trace created when the real event occurs?
  • If there is a trace, which condition or action stops the path?
  • Does the action work when tested separately?
  • What was the actual state of the entities at that time?
  • What exactly did you expect and what happened?

These questions break a large problem into smaller ones. If no trace appears, investigate the trigger or whether the automation loaded. If the trace exists and ends at a false condition, changing the final action will accomplish nothing.

DEALS · OFFICIAL STORE

Discounts on SONOFF smart home

Wi-Fi switches, relays, sensors, LED strips and more. Deals change frequently in the official store.

Coupon: TECNOYFOTO (10% off at checkout)

View official deals Affiliate link Affiliate link · SONOFF store

The four layers of failure

1. YAML syntax

The document cannot be parsed correctly into lists, maps, and values. A tab character, an unclosed quotation mark, or indentation that breaks the structure belongs to this layer.

data:
  title: "YAML Course
  message: "The door is open."

The quotation mark for title is not closed, so the document cannot be parsed as intended. Incorrect indentation can also make YAML invalid or build a different structure. At this layer, the parser message, the reported line, and a visual comparison of indentation levels are useful.

Do not automatically fix the line named in the error. A parser often detects the problem only after the structure has become impossible, while the actual cause appears just above it: an open quotation mark, an unclosed bracket, or incorrect indentation.

2. Home Assistant schema

The YAML is valid, but does not represent a valid automation. This fragment is perfectly legible YAML:

actions: light.turn_on

However, actions must contain a sequence in a form Home Assistant supports. A YAML parser does not understand the concepts of triggers, conditions, or actions; it sees only a key and a string. Home Assistant applies its schema and rejects the structure.

A misspelled key, a missing required field, or a value of the wrong type also belongs to this layer. Configuration validation and reload messages usually provide the best clues.

3. Reference or execution

The automation loads and starts running, but it tries to use something unavailable, or an action returns an error:

- action: light.turn_on
  target:
    entity_id: light.course_livng_room

The typo in livng can pass structural validation. The failure appears when Home Assistant resolves the target or runs the action. At this layer, we examine states, actions, traces, and logs.

An entity whose state is unavailable, a disconnected integration, or insufficient permissions can also cause execution errors even when the indentation is correct.

4. Logic

Everything is valid, and each piece could work, but the decisions do not describe the desired behavior:

triggers:
  - trigger: state
    entity_id: binary_sensor.course_front_door
    to: "on"
conditions:
  - condition: state
    entity_id: binary_sensor.course_front_door
    state: "off"

The automation triggers when the door opens and immediately requires the door to be closed. A race condition could occur if the state changed again at exactly that moment, but under normal circumstances this condition blocks the intended path.

No validator can know that you intended to turn on the light. For Home Assistant, a false condition is a valid result, not an error. Diagnose logic by comparing the requirements, the actual states, and the path the automation followed.

Validate before restarting

The validation section under Settings → Tools → YAML lets you check the configuration. Use it after editing manual files and before restarting.

Validation can detect syntax problems and many schema errors. It does not apply your changes, prove that an entity will be available later, or confirm that an automation takes the intended branch.

If the result indicates a path such as:

data['automation'][2]['actions'][0]['target']

read it as a path:

  1. Enter automation.
  2. Find the third item in the list; indexes start at zero.
  3. Enter actions.
  4. Look at the first action.
  5. Check target.

Not every message identifies the filename clearly, especially when includes are involved. Use the method from the previous chapter to determine which file provided that part of the structure.

Reload only what you’ve changed when possible

After a successful validation, specific sections such as automations or scripts can be reloaded from the same YAML tool. A selective reload is faster and disrupts the home less than a full restart.

Not everything can be reloaded. If the integration or section does not appear among the available options, you will need to restart Home Assistant. Follow this sequence:

  1. Save the file.
  2. Validate the configuration.
  3. Reload the section if Home Assistant offers it.
  4. Restart only when the type of change requires it.
  5. Confirm that the entity or automation is loaded.

A successful validation followed by a reload is not a functional test. We still need to reproduce the scenario.

Traces show what happened, not what we think happened

Each automation run generates a step-by-step trace. From the editor or the automation list, we can open Traces and see:

  • Which trigger started the run.
  • What values and variables were available.
  • What conditions returned true or false.
  • Which branch of choose was selected.
  • Which actions ran and how long they took.
  • Where an error occurred.

In manually written automations, assign an id, so Home Assistant can store their traces:

- id: "course_entry_light"
  alias: "YAML Course - Entry light"
  # rest of automation

Do not confuse Run actions with firing the real trigger. That button skips triggers and top-level conditions. It is useful for checking the action sequence, but it cannot prove that a trigger ID or the trigger variable works. For those cases, reproduce the real state change or use a controlled test that supplies the required context.

A trace with no errors can still reveal the problem: perhaps Home Assistant followed default because no choose option matched, or a condition returned false because the actual state differed from what we assumed.

Check states and actions separately

In Settings → Tools → States, search for the entities involved. Copy their exact identifiers and inspect their actual states, not the friendly text shown on a dashboard card.

Remember that modifying a state from this tool temporarily changes the internal representation. It does not control the physical device. It is useful to simulate an input and can trigger automations, but the device or its integration can overwrite the value later.

In Actions, run the smallest relevant action:

action: light.turn_on
target:
  entity_id: light.course_living_room

If this fails, the automation trigger is not the problem. Check the entity, integration, availability, and action data. If it works, return to the trace and find what prevented the automation from reaching it.

Test templates with edge cases

The template editor displays results in real time. Do not test only the convenient case. For a temperature, check one value above the threshold, one below it, and the states unknown and unavailable.

{% set entity = 'sensor.course_living_room_temperature' %}
{{ has_value(entity) and states(entity) | float < 25 }}

The editor does not automatically reproduce an automation’s execution context. Variables such as trigger and this exist only in the appropriate contexts. If a template depends on trigger.to_state, we can first test the independent portion or carefully define simulated data, but the final verification must use a real automation run.

Read the logs after reproducing the problem

Logs are more useful when we know when the failure was reproduced and which component was involved. Find the message closest to that test, read the surrounding entries, and preserve the exact error text.

Do not enable global debug logging for days “just in case.” For an integration problem, Home Assistant lets you enable debug logging for that integration, reproduce the failure, and disable logging to download the file. The additional detail may contain sensitive information, so review it before sharing.

Reduce the problem without destroying its context

When a block has twenty conditions, three scripts, and several templates, create a test copy or temporarily disable pieces in a controlled way. Keep:

  • One reproducible trigger.
  • The suspicious condition.
  • The smallest safe action.
  • The necessary entities.

If the problem disappears, add back one piece at a time. If it remains, you now have a small example that is easier to read and share.

Save a copy of the original fragment and avoid making five changes at once. If the system starts working, you need to know which change fixed it; if it gets worse, you need to be able to return to a known state.

How to ask Codex for help usefully and safely

A request such as “fix this YAML” leaves too much to guess. Provide:

  • Exact version of Home Assistant.
  • Where the block lives: an automation created in the user interface, a manual file, a script, or a package.
  • The requirement in plain language.
  • Expected and observed behavior.
  • Complete error message or trace step where it stops.
  • A minimal YAML example with secrets and personal data replaced.

A good request would be:

Home Assistant 2026.8.1. This manual automation loads, but traces
end at conditions/0. The door is open, and I expected it to turn on
the light.
Explain the cause before proposing the change and give me the minimum patch.
Don't change the entity_id.

After receiving a proposed change, do not paste it blindly. Check which lines it changes, whether it introduces concepts you do not understand, and whether it preserves the negative cases. Codex can spot patterns and explain messages, but it does not know the actual state of your home unless you provide it.

Never share tokens, passwords, webhooks, secrets.yaml, unreviewed full configuration copies, or logs that may contain credentials. Replacing a secret with REDACTED does not prevent anyone from diagnosing the structure.

Practice environment error clinic

The practice environment contains five deliberately broken files. Do not copy them into your active configuration. For each one:

  1. Write down the symptom you expect.
  2. Classify the failure by layer before correcting it.
  3. Locate the responsible line or decision.
  4. Make the minimum change.
  5. Decide which tool shows that it is fixed.

The solution explains the reasoning instead of merely showing the final YAML. Validation detects some failures; others require states, actions, or a trace. That distinction is the main lesson.

See the diagnosis summary
  1. Syntax: title opens a quote that is not closed. The quote is corrected and tested with validation.
  2. Schema: actions contains a string instead of the expected sequence. A generic YAML validator may accept it; Home Assistant must check it.
  3. Reference: light.course_livng_room contains a typo. Find the actual identifier in States and test the smallest relevant action.
  4. Logic: the door triggers the automation when it changes to on, but a condition immediately requires off. The trace will show a false condition, not a syntax error.
  5. Template: the numeric conversion does not account for unknown or unavailable. Check has_value() first and convert only afterward.

The practice environment contains the complete solution and identifies the specific tool used to verify each correction.

Your protocol from now on

When something does not work, do not change random keys until the result changes. Follow this order:

  1. Define the expected and observed behavior.
  2. Confirm that the file and automation have loaded.
  3. Validate the syntax and schema.
  4. Reload selectively when possible.
  5. Reproduce the event once and record the time.
  6. Open the trace; if it does not exist, investigate the trigger.
  7. Check states and test the smallest relevant action.
  8. Check templates with normal cases and unavailable states.
  9. Read the related logs.
  10. Change one thing and repeat the test.

In the final chapter, we will apply this protocol to a complete project. Getting it to “work once” will not be enough: we will build an organized solution, test its positive and negative paths, and explain every decision it makes.