Trying to test if variable is none then set it to something

I’m trying to test to an empty response from an action call and if it is empty then set it to a value:

    response_variable: generated_content
    continue_on_error: true
    action: google_generative_ai_conversation.generate_content
  - if:
      - condition: template
        value_template: "{{ generated_content is none}}"
    then:
      - generated_content: Google AI Error
  - if:
      - condition: template
        value_template: "{{ 'no obvious motion detectd' in generated_content.text | lower}}"
    then:
      - stop: ""

However the first “then” statement is generating an error

Message malformed: Unable to determine action @ data['sequence'][6]['then'][0]

Any help fixing this would be appreciated!

That will never work. See: https://www.home-assistant.io/docs/scripts/#scope-of-variables

Even if you use the correct syntax:

    then:
      - variables:
          generated_content: Google AI Error

As soon as you exit that if block the variable reverts to its previous state.

Just set the variable using a Jinja expression instead of the if statements.

    - action: sonos.get_queue
      target:
        entity_id: "{{entity_id}}"
      response_variable: queue
    - variables:
        queue_len: '{{ queue[entity_id] | length }}'

You’ll need to figure out the Jinja expression for your use case. Look at the docs for some help

@Tom_I - I’m very new to this so pretty much nothing in the documents makes sense. I assumed that the response_variable: generated_content on the first line of the snippet declared the variable, which should have been outside the if statement scope.

I wasn’t trying to declare a second variable with the same name as the former within the IF block scope; I was trying to give it a value if the google_generative_ai action failed.

I know. You still can’t change the value inside the block and expect it to be available outside.

Building on Pete’s example above you could try this:

    - action: google_generative_ai_conversation.generate_content
      response_variable: generated_content
      continue_on_error: true
    - variables:
        filtered_content: "{{ 'Google AI Error' if generated_content | length == 0 else generated_content }}"
1 Like

Thanks Tom_I. With your help, I am getting closer. I now have:

  - metadata: {}
    data:
      prompt: >-
        Check images 1-3 and briefly describe any movement.  If a person or car
        is moving, give details. If no motion,  reply "No Obvious Motion
        Detected".  Keep it short for a phone notification.
      image_filename:
        - ./www/snapshots/{{ camera_name }}_snapshot1.jpg
        - ./www/snapshots/{{ camera_name }}_snapshot2.jpg
        - ./www/snapshots/{{ camera_name }}_snapshot3.jpg
    response_variable: generated_content
    continue_on_error: true
    action: google_generative_ai_conversation.generate_content
  - variables:
      filtered_content: >-
        {{ 'Google AI Error' if generated_content is none else
        generated_content.text }}
  - if:
      - condition: template
        value_template: "{{ 'no obvious motion detected' in filtered_content | lower}}"
    then:
      - stop: ""
    else:
      - action: shell_command.fixup_jpeg
        data:
          image_file: ./www/snapshots/{{ camera_name }}_snapshot3.jpg
      - delay:
          hours: 0
          minutes: 0
          seconds: 0
          milliseconds: 500
      - metadata: {}
        data:
          title: "{{ camera_name }} Motion Detected"
          message: "{{filtered_content}}"
          data:
            images:
              - /config/www/snapshots/{{ camera_name }}_snapshot3.jpg
        action: notify.family_sms
mode: single

However, occasionally I’m getting the following error:

Template variable error: 'generated_content' is undefined when rendering '{{ 'Google AI Error' if generated_content is none else generated_content.text }}'

I’m assuming the error occurs when the google_generative_ai_conversation.generate_content call fails. I thought that would have been caught by the if generated_content is none clause. That is what I was hoping was the test for “undefined”.

Any additional words of wisdom?

Late addition - I saw a reference to == empty, so I’m trying that as a test for undefined now.

{{ 'Google AI Error' if generated_content is not defined else generated_content.text }}

I am setting filtered_content to an error message string when the response variable, generated_content, does not exist (i.e. the google conversation call fails). If the response variable does exist, then I am setting filtered_content to the text string contained within generated_content.test. generated_content.text should only be used after generated_content has been confirmed as being set.

The problem I’m having is the correct test to determine if the response variable, generated_content, exists. Multiple examples on the web show is none, is defined, == empty. Which is the correct test?

@Rick - I’ll try is not defined next.

My earlier post (deleted now) was incorrect; I failed to recognize that you have two separate variables, generated_content and filtered_content.

The problem definitely looks to be that generated_content is sometimes not defined, so the is none test throws an error. Presumably you are seeing both the possibility of the variable being undefined and being none (which are two different things). I’d use this:

- variables:
      filtered_content: >-
        {{ 'Google AI Error' if generated_content|default(none) is none else
        generated_content.text }}

Dominic - thanks. Part of the problem is my lack of understanding of the terminology and therefor inability to Google for solutions. To me, the line response_variable: generated_content defines the variable.

If google_generative_ai_conversation.generate_content fails, then generated_content is left uninitialized, and therefore attempting to access generated_content.text results in a failure.

So my quandary is how to test for generated_content being uninitialized after a failure of the calling function. I cannot find a definitive solution in the HomeAssistant documentation, and I’ve now seen four different “tests” leaving me totally confused.

I realize there is the additional possible error in that generative AI conversation could “succeed” and still return an uninitialized text string. I’m going to ignore that possibility for now and blissfully assume it would just be set to an empty string.

Variable nuances are an unfortunately vexing part of scripting and response variables, in particular, are a bit of a black box. What you say there is a reasonable expectation, but I don’t think it’s guaranteed, especially if the response variable is coming from something other than a script. Just going by the error message that you’re seeing, you’re clearly hitting a situation where generated_content is not defined.

I wonder if you hit this issue, which was just fixed in the March release (2025.3).

Just wanted to update the thread on my results. It looks like == empty was the winner (with a big thanks to Tom_I for putting me on the right track):

.
.
.
    response_variable: generated_content
    continue_on_error: true
    action: google_generative_ai_conversation.generate_content
  - variables:
      filtered_content: >-
        {{ 'Google AI Error' if generated_content == empty else
        generated_content.text }}
  - if:
      - condition: template
        value_template: "{{ 'no obvious motion detected' in filtered_content | lower}}"
    then:
      - stop: ""
    else:
.
.
.

Thanks everyone for your help.

EDIT – Rick and Dominic point out in latter posts that

is not defined

is the correct test, and not

== empty

as I have used above.

Did you try is not defined ?

I’d expect you can replace empty with dhudvbxcpycg and find no difference in behavior.

You’re checking equality of two undefined variables. empty is not some special object; it’s simply a variable that hasn’t been defined. And any two undefined variables will equal each other. {{ gecjrsv == ptefjtv }} will render true because they are both undefined variables. Why not explicitly check if generated_content is undefined instead of checking if it is equal to some random undefined variable?

1 Like

You marked the approach with empty as a solution but, if that works, it’s at best by accident and should not be used by others.

If you search the web for information about Jinja–or, if you really want to tempt death, use an LLM to write the code for you–you can often find “solutions” that work for other platforms that have extended Jinja in ways that are not applicable to Home Assistant. The only authoritative documentation on Jinja for Home Assistant is the Template Designer Documentation and the Home Assistant Templating documentation. Neither of those documents discusses an empty function, filter, or other thing.

So there is no such thing as empty. That’s just an undefined variable, same as hogwarts. You can prove this to yourself by trying the following in the Template Editor:

{{ empty }}

And if you feel like running a second experiment,

{% set empty = 'This is a string assigned to the variable named empty.' %}
{{ empty }}

Incidentally, it looks like (using the Template Editor) if you try to compare two undefined variables with ==, you get true (rather than an error). So at best what you’re doing incidentally does what is undefined would do, and that’s only because you haven’t defined empty as a variable.

2 Likes