Having problems with latest jinja

Many of my scripts and automations are broken with the latest HA update that includes a jinja update.

I used to be able to do things as follows (given there’s a variable named heat)

  variables:
     other: "{{ heat['fan on'] | float(0) + ... }}"

But with recent changes these fail when there is no value looked up.

The solutions is to capture the lookup into a variable, then perform the arithmetic.

   variables:
       temp: "{{ heat['fan on'] }}"
       other: "{{ temp | float(0) + ... }"

Something is really wrong here as this doesn’t make sense. And I have to rewrite many scripts/automations with this unexpected and illogical change.

This doesn’t make sense to me.

Can you show the code that sets the heat variable?

And also what the ... is?

action: notify.persistent_notification
metadata: {}
data:
  message: "{{ ('{ \"hello\": \"there\" }' | from_json)['hellox'] | float(0) }}"

The above fails with an error message that ‘hellox’ is not found. This is a deviation from prior versions where the default of 0 is expected. We do expect a “not found” error from somejson.hellox but not from somejson['hellox'].

Further,

action: notify.persistent_notification
metadata: {}
data:
  message: "{{ ('{ \"hello\": \"there\" }' | from_json)['hellox'] }}"

works as expected, yielding empty without error.

Only when the x[‘y’] construct is nested within an expression (such as with
a filter of | float(0)) does the error stop the template. And this is new behavior as this worked as expected with 2025.2.5

When you use a double single quote like '', Jinja interprets that as an empty string. You’re trying to use it as a single quote mark.

You have two options for quotes:

'Option 1'

and

"Option 2"

The following is not an option; it doesn’t parse to the string “invalid option” but to [empty string][expression that is invalid][empty string]:

''invalid option''

You can even see that bear out in the way that the automatic highlighting in this forum breaks those examples down.

So that’s probably why your “new” code works: it doesn’t use quote marks incorrectly.

I am seriously not following. The problem is that the same exact construct works when not nested in larger arithmetic expression, but fails when in a larger expression. Its like the rules have changed for attribute lookup with 2025.3 with the latest jinja.

Look closely at your two code examples.

The first one:

{{ (''{ "hello": "there" }'' | from_json)[''hellox''] | float(0) }}
{#  ^^  wrong quote use   ^^              ^^      ^^  #}

The second one:

{{ ('{ \"hello\": \"there\" }' | from_json)['hellox'] }}
{#  ^    correct quote use   ^              ^      ^  #}

Thank you for your attention, trying to work through this as best I can, and seems to me like a change with latest jinja, just trying to point out and make some sense.

I don’t see how this can be due to a Jinja upgrade. Your code just uses incorrect syntax.

Ok, I copied & pasted some yaml incorrectly. I have fixed, and my point stands, I think? I’m not getting syntax errors or errors from from_json.

No. This expression in Jinja is an empty string: ''. It’s not a quote!

If you give Jinja this code to parse:

'' Hello ''

Jinja parses that as [empty string] [expression “Hello” (which is not an operator, so it’s invalid)] [empty string].

That’s different than either "Hello" or 'Hello', each of which parses as the string Hello.

Yes, sorry for the syntax copy & paste error. My point about the difference of x[‘y’] alone vs. in a larger expression still stands. This works x['y'] but x['y'] | float(0) doesn’t. And used to with prior HA.

If you have a test case that makes the point you think you’re trying to make with correct use of quotations, please share it.

alias: Test Problem
description: ""
triggers: []
conditions: []
actions:
  - action: notify.persistent_notification
    metadata: {}
    data:
      message: "{{ ('{ \"hello\": \"there\" }' | from_json)['hellox'] | float(0) }}"
  - action: notify.persistent_notification
    metadata: {}
    data:
      message: "{{ ('{ \"hello\": \"there\" }' | from_json)['hellox'] }}"
mode: single

The first action errors, and the second doesn’t. This is a deviation from prior HA’s. The only difference between these two expressions is that the ['hellox'] expression is nested in a larger expression. Prior HA’s allowed both of these action expressions to work the same – without error.

The error that is issued is that ‘hellox’ is not found. This is incorrect behavior as this should not issue a not found error, but instead proceed to | float(0).

Of course, we expect an error from json.hellox, but not from json['hellox']. And why it is now allowed alone, but not within a larger expression is at issue.

What’s the error? Is it that the dict object has no attribute ‘hellox’?

What you have now is certainly valid Jinja syntax. There is a significant difference between the two cases.

The second expression, where you don’t use the float filter, evalutes to undefined, because your JSON dictionary only has a key named hello, and not hellox. But you don’t get an error, because Jinja can complete the evaluation and figure out that it’s undefined; it tells HA that the expression is undefined, and HA just treats the undefined value as an empty string.

The first expression, however, will give you

 'dict object' has no attribute 'hellox'

That’s because Jinja can’t finish the evaluation. The Jinja engine needs to apply the float filter to something, but when it tries to get that something, it hits an undefined error.

You can eliminate that problem with the default filter, like this:

{{ ('{ \"hello\": \"there\" }' | from_json)['hellox'] | default(0) | float(0) }}

That’s the recommended way to handle the possibility that an expression being piped into a filter is undefined. You can verify this in the Template Editor. Try:

{{ ('{ \"hello\": \"there\" }' | from_json)['hellox'] is defined }}

You should get false.

I believe the default filter is a relatively recent addition. So depending on what version of Jinja you upgraded from, you might well be experiencing a difference in behavior–although I don’t know what Jinja would do in this scenario before addition of the default filter.

The error message is in regarding the dictionary lookup, not the | float(0).

The difference from prior HA’s is that x['y'] | float(0) now fails whereas it didn’t prior versions.

Right. Because it never gets to the float; it hits an error trying to get the value to pass to float–so that’s what it complains about, as explained in my post above.

Yes, but this is new with 2025.3

And the error is that the attribute is not found.

And this is new as using the x[‘y’] construct alone still does not error even with new HA.