Troubleshooting template errors
This page lists template error messages you might run into, what each one means in plain language, and how to fix it. If the message you see doesn’t match exactly, look for the closest one. The names of types and variables change, but the shape of each error stays the same.
You can find most of these messages in the template editor and in the logs. If a template in the conditions or actions of an automation or script fails, the trace of the run also shows the error, on the step where it happened. For the steps to open a trace, refer to Viewing the traces of an automation.
For a general debugging workflow, refer to Debugging templates.
Undefined value errors
UndefinedError: ‘foo’ is undefined
Symptom
The template editor or the log shows the error UndefinedError: 'foo' is undefined. Or, the result is empty, and the template editor shows 'foo' is undefined as a warning. In the log, the warning reads Template variable warning: 'foo' is undefined when rendering '...'.
Description
The template is trying to use a variable named foo that doesn’t exist. Either the name is misspelled, or the variable was never set.
If you only show or check the variable, as in {{ foo }} or {% if foo %}, you get the warning. The error only appears when the template uses the variable further, for example in {{ foo + 1 }} or {{ foo.bar }}.
Resolution
- Check the spelling of every name in the template.
statesandstateare different;trigger.to_stateandtrigger.tostateare different. - If you use a variable with
{% set name = value %}, make sure thesetruns before the variable is used. - If you expect the variable to come from an automation trigger (
trigger.*) or a template entity (this.*), remember these only exist in those contexts. They aren’t available in the template editor under Settings > Tools > Template. To test the template in the editor anyway, define the variables yourself. For the steps, refer to Testing a template.
UndefinedError: ‘dict object’ has no attribute ‘foo’
Symptom
The template editor or the log shows the error UndefinedError: 'dict object' has no attribute 'foo'. Or, the result is empty, and the template editor shows the same message as a warning.
Description
You tried to read a key named foo from a dictionary, but that key doesn’t exist.
If you only show the value, as in {{ data.foo }}, you get the warning. The error only appears when the template uses the value further, for example in {{ data.foo + 1 }}.
Resolution
- Use
.get('foo', default_value)to return a default when the key is missing:data.get('foo', 0). - Or check for the key first with
if 'foo' in data. - If the dictionary comes from a JSON response, show it with
{{ data | tojson }}to see exactly which keys are there.
UndefinedError: ‘None’ has no attribute ‘state’
Symptom
The template editor or the log shows the error UndefinedError: 'None' has no attribute 'state'. Or, the result is empty, and the template editor shows the same message as a warning.
Description
You used dot notation like states.sensor.temperature.state, and the entity sensor.temperature doesn’t exist, or isn’t set up yet. states.sensor.temperature then returns None, which has no state. Usually, the entity ID is misspelled.
If you only show the value, as in {{ states.sensor.temperature.state }}, you get the warning. The error only appears when the template uses the value further, for example in {{ states.sensor.temperature.state | float }}.
Resolution
- Use
states('sensor.temperature')instead. The function version returns the text'unknown'for missing entities instead of raising an error, which is safer. - Verify the entity ID in Settings > Tools > States.
No first item, sequence was empty
Symptom
The template editor or the log shows the error UndefinedError: No first item, sequence was empty. Or, the result is empty, and the template editor shows No first item, sequence was empty as a warning. For last, the message is No last item, sequence was empty.
Description
You used first or last on a list that turned out to be empty. There is nothing to return.
If you only show the result, you get the warning. The error only appears when the template uses the result further, for example in {{ (items | first).name }}.
Resolution
Check the list length first, or use default:
{% set items = [] %}
{{ items | first | default('nothing') }}
nothing
Type errors
TypeError: can only concatenate str (not "int") to str
Symptom
The template editor or the log shows the error TypeError: can only concatenate str (not "int") to str. Other math operations give a similar message. For example, "22.5" - 5 gives TypeError: unsupported operand type(s) for -: 'str' and 'int'.
Description
You’re trying to do math between a piece of text and a number. This happens most often with entity states, because every state is stored as text. "22.5" + 5 doesn’t work.
Resolution
Convert the text to a number first with | float(0) or | int(0):
{{ states('sensor.temperature') | float(0) + 5 }}
27.5
The 0 is a fallback used when the conversion fails (for example, when the sensor is unavailable). For details, refer to Types and conversion.
TypeError: ‘>’ not supported between instances of ‘str’ and ‘int’
Symptom
The template editor or the log shows the error TypeError: '>' not supported between instances of 'str' and 'int'. The message shows the operator you used, such as < or >=.
Description
You compared a piece of text with a number, for example, states('sensor.temperature') > 20. Entity states are stored as text, so the comparison doesn’t work.
Resolution
Convert the text to a number first with | float(0) or | int(0):
{{ states('sensor.temperature') | float(0) > 20 }}
True
ValueError: Template error: float got invalid input ‘unavailable’ when rendering template ‘…’ but no default was specified
Symptom
The template editor or the log shows the error ValueError: Template error: float got invalid input 'unavailable' when rendering template '...' but no default was specified. The same message comes from other functions, with their name instead of float. These include int, as_timestamp, strptime, round, and the timestamp_* functions.
Description
A conversion function got a value it can’t convert, and you didn’t give it a default to use instead. The value in quotes shows what it got. Common values are unavailable or unknown from an entity that isn’t ready, and None from an attribute that doesn’t exist.
Resolution
Give the function a default value to use instead, for example, | float(0) for float:
{{ state_attr('light.kitchen', 'brightness') | float(0) }}
0
If the value is the state of an entity, you can also check first whether the entity has a valid state, using has_value. has_value only checks entity states, not attributes.
as_datetime only gives this error for a value that isn’t text, such as None. If it gets text it can’t read as a date, such as unavailable, it returns None instead of an error.
TypeError: object of type ‘generator’ has no len()
Symptom
The template editor or the log shows the error TypeError: object of type 'generator' has no len().
Description
You tried to count or measure an iterable directly. Filters like map, select, reject, selectattr, and rejectattr return iterables, not lists. You can only count them after you turn them into a list.
Resolution
Add | list to turn the iterable into a list first:
{{ states.light | selectattr('state', 'eq', 'on') | list | count }}
3
For details, refer to Iterables look like lists, but are not.
Syntax errors
TemplateSyntaxError: expected token ‘end of statement block’, got ‘X’
Symptom
The template editor or the log shows the error TemplateSyntaxError: expected token 'end of statement block', got 'X'. Inside {{ ... }}, the message says 'end of print statement' instead.
Description
There is a typo or an unexpected character inside a {% ... %} or {{ ... }} block. Something is written that the template engine doesn’t recognize. The message shows what it found instead of X.
Resolution
- Check for missing commas, brackets, or quotes.
- Verify that operators are spelled right (
==,!=,and,or,not,in). - Make sure you used
is not, notnot is.
TemplateSyntaxError: Unexpected end of template
Symptom
The template editor or the log shows the error TemplateSyntaxError: Unexpected end of template. The rest of the message names the block that isn’t closed, for example, The innermost block that needs to be closed is 'if'.
Description
A {% if %}, {% for %}, {% set %}, or {% macro %} block was opened but not closed. Every block tag needs a matching {% endif %}, {% endfor %}, {% endset %}, or {% endmacro %}.
Resolution
- Count the opening and closing tags. If you have two
{% if %}, you need two{% endif %}. - Indent the template in the editor so you can see the structure.
TemplateSyntaxError: tag name expected
TemplateAssertionError: No test named ‘foo’
Symptom
The template editor or the log shows the error TemplateAssertionError: No test named 'foo'. If the test is inside an {% if %} block or an inline if, the message is TemplateRuntimeError: No test named 'foo' found. instead.
Description
After is, you used a test name the engine doesn’t know. Test names are lowercase. For example, is none works, but is None gives the error No test named 'None'.
Inside an {% if %} block or an inline if, the template engine only checks the test name when that part of the template runs. If it doesn’t run, there’s no error until the condition changes.
Resolution
Check the test name against the template functions reference. Common tests are defined, none, number, string, boolean, iterable, mapping, even, odd, eq, gt, lt, and in. Aliases like equalto, greaterthan, and lessthan also work.
TemplateAssertionError: No filter named ‘foo’
Symptom
The template editor or the log shows the error TemplateAssertionError: No filter named 'foo'. If the filter is inside an {% if %} block or an inline if, the message is TemplateRuntimeError: No filter named 'foo' found. instead.
Description
After |, you used a filter name the engine doesn’t know. Usually, the name is misspelled.
Inside an {% if %} block or an inline if, the template engine only checks the filter name when that part of the template runs. If it doesn’t run, there’s no error until the condition changes.
Resolution
Check the filter name against the template functions reference.
Other template errors
TemplateError: Invalid entity ID ‘sensor.Temperature’
Symptom
The template editor or the log shows the error TemplateError: Invalid entity ID 'sensor.Temperature'.
Description
The entity ID in the template isn’t a valid entity ID, and no entity matches it. For example, it contains capital letters or spaces. Entity IDs only use lowercase letters, numbers, and underscores, with one period between the domain and the name. Neither part can start or end with an underscore, and the entity ID can’t contain two underscores in a row.
You only get this error with dot or bracket notation, such as states.sensor.Temperature or states['sensor.Temperature'], and with state_translated and state_attr_translated. Functions like states, is_state, and state_attr don’t check the entity ID. If they can’t find the entity, they return unknown, false, or none.
Resolution
Copy the entity ID from Settings > Tools > States.
TemplateError: Use of ‘states’ is not supported in limited templates
Symptom
The log shows the error TemplateError: Use of 'states' is not supported in limited templates. The name in quotes shows which function you used.
Description
The template runs in a place that only supports limited templates, such as trigger_variables, some trigger options, or the enabled option of a trigger, condition, or action. For the functions that aren’t available there, refer to What limited templates can’t use. For what else happens, depending on the field, refer to How you notice a limited template error.
People most often run into this with now() in trigger_variables.
Resolution
Move the part that uses these functions to a place that supports full templates. For example, if you only need the value in the conditions or actions of an automation, use variables instead of trigger_variables. variables supports full templates, but is only evaluated after the automation starts. That’s why the trigger options themselves can’t use it.
SecurityError: access to attribute ‘append’ of ‘list’ object is unsafe
Symptom
The template editor or the log shows the error SecurityError: access to attribute 'append' of 'list' object is unsafe. Or, the result is empty, and the template editor shows the same kind of message as a warning.
Description
Templates run in a protected environment that doesn’t allow changing lists or dictionaries, or accessing internal attributes. Calling append, update, or pop causes this error right away. If you only read an attribute that starts with _, you get the warning. The error only appears when the value is called or used further.
Resolution
Build a new list instead of changing the existing one. For example, use {% set items = items + ['new'] %} instead of {{ items.append('new') }}. To collect values in a loop, use a namespace:
{% set ns = namespace(items=[]) %}
{% for name in ['kitchen', 'hall'] %}
{% set ns.items = ns.items + [name] %}
{% endfor %}
{{ ns.items }}
['kitchen', 'hall']
For other ways to build a new list, such as sorting or removing items, refer to Methods that change a list.
TemplateError: Template output exceeded maximum size of 262144 characters
Symptom
The template editor or the log shows the error TemplateError: Template output exceeded maximum size of 262144 characters.
Description
The template produced more than 262,144 characters of text. Home Assistant limits how large the result of a template can be.
Resolution
Return less data. For example, filter a list down to the entities you need, or return a count instead of the full list.
YAML errors
invalid key: "{"states(‘sensor.temperature’)": None}"
Symptom
When Home Assistant loads your YAML configuration, it shows the error invalid key: "{"states('sensor.temperature')": None}", with the file and line. If the template starts with {%, the message is found character '%' that cannot start any token instead.
Description
Your YAML file contains a template with unquoted braces. If the value starts with {{, YAML reads the braces as a mapping, and the template ends up as an invalid key.
Resolution
Wrap the single-line template in quotes, or use a multi-line block scalar:
# Correct: quoted
value_template: "{{ states('sensor.temperature') }}"
# Correct: multi-line
value_template: >
{{ states('sensor.temperature') }}
For the full set of quoting rules, refer to Templates in YAML.
Next steps
- For a systematic approach to narrowing down any template problem, refer to Debugging templates.
- If the error came from a quoting or indentation issue, refer to Templates in YAML.
- If the error involves state values being text, refer to Working with states.
Still stuck?
The Home Assistant community is quick to help: join Discord for real-time chat, post on the community forum with your template and the exact error message, or share on our subreddit.
AI assistants like ChatGPT or Claude can also explain or fix templates when you describe what you want in plain language. Paste in your template and the error message.