<p>I believe I have a workaround and can (roughly) explain what's going on here.</p>

<p>First, the workaround:</p>

<p><strong>Use array syntax to test the existence of your custom fields instead of object syntax.</strong></p>

<pre><code>{# This works #}
{% if entry['someField'] is defined %} ... {% endif %}
</code></pre>

<p>Using array syntax for your conditional will result as true if your field does exist and false if it does not. Using object syntax results in false positives where the conditional always returns true even if a field doesn't exist:</p>

<pre><code>{# FALSE POSITIVES: These return true if a field doesn't exist #}

{% if entry.someField is defined %} ... {% endif %}
{% if attribute(entry, 'someField') is defined %} ... {% endif %}
</code></pre>

<p>I believe the false positive occurs using object syntax when the object has or is extending another object that uses a <code>__call()</code> method. Twig will test to see if it can find an <code>attribute</code> or a <code>method</code>.  In the case it can't find an attribute on an object, it will look for a method.  And if it can't find a method on the object, it will check for the existence of a <code>__call()</code> method and if the <code>_call()</code> method exists it returns true, creating the undesired result of also returning true for any variable that doesn't exist on an object that uses a <code>__call()</code> method.</p>

<p>I haven't dug into the code, but it seems that using the array syntax doesn't trigger a search for a potential method associated with the <code>__call()</code> behavior.</p>

<hr>

<p>A couple related articles can be found on Straight Up Craft:</p>

<ul>
<li><a href="https://straightupcraft.com/articles/how-to-check-if-a-variable-or-value-exists-using-twig" rel="noreferrer">How to check if a variable or value exists using Twig</a></li>
<li><a href="https://straightupcraft.com/articles/testing-if-something-exists-is-defined-length-is-not-null-is-not-empty" rel="noreferrer">Testing if something exists: is defined, length, is not null, is not empty</a></li>
</ul>

CC BY-SA 3.0
2016-01-18T19:34:03.553Z
This should go into the official documentation! ... I just dumped several hours into researching this odd behaviour :(
m9dfukc
CC BY-SA 3.0
2016-03-21T10:02:47.240Z
Sweet, that resolves it. Thanks for sharing!
medoingthings
CC BY-SA 4.0
2021-01-06T02:38:36.533Z
This had me flummoxed, thank you!
Judd Lyon
CC BY-SA 4.0
2019-10-31T23:16:56.060Z
2019 and this is still an issue - and this appears to still be a work-around. Thanks!
Mike
CC BY-SA 3.0
2015-10-24T16:38:32.337Z
2017-03-15T02:12:23.760Z
2017-03-15T02:12:23.760Z
Ben Parizek
<p>I was able to resolve this issue by creating a custom plugin that uses a service and template variables. The service will accept the content object and field name. You can reference how to write a conditional to check if the field is set (<a href="http://buildwithcraft.com/classreference/models/BaseElementModel#getFieldValue-detail" rel="nofollow">http://buildwithcraft.com/classreference/models/BaseElementModel#getFieldValue-detail</a>). The service is then used in the template variables and will return true or false based on if the field is set.</p>

<p>Craft Template Twig Example</p>

<pre><code>{{ (craft.pluginName.isFieldDefined(e, 'someField') ? e.someField : false) }}
</code></pre>

<p>Sorry, I can't post a full code example.</p>

CC BY-SA 3.0
2015-03-04T19:15:26.307Z
2015-03-04T20:27:19.063Z
2015-03-04T20:27:19.063Z
Mike Zens
<p>I came across this while trying to check if object has method. I found out that <code>is defined</code> always returns true and some other options would return always null (even if the method existed) so I ended up writing a twig extension (which was faster than trying to solve the problem):</p>
<pre><code>/**
 * @param object $entity
 * @param string $method
 *
 * @return bool
 */
public function twig_method_exists($entity, string $method): bool
{
    if (!is_object($entity)) {
        throw new InvalidArgumentException('Given entity is not of type object, got: '.get_class($entity));
    }

    if (empty($method)) {
        throw new InvalidArgumentException('Method name empty');
    }

    return method_exists($entity, $method);
}

</code></pre>
<p>And i use it like this in the twig</p>
<pre><code>{% if method_exists(entity, 'getCreatedBy') %}
    ({{ entity.createdBy.name }})
{% endif %}
</code></pre>

CC BY-SA 4.0
2020-08-21T08:19:15.343Z
2020-08-21T08:19:15.343Z
Tuomas Valtonen
<p>I had a similar issue when using an if statement to define a block element. The correct way doing this will be following:</p>

<pre><code>{% block metaOgImage %}
  {% if og.image is defined %}
   &lt;meta property="og:image" content="{{ og.image }}"&gt;
  {% endif %}
{% endblock %}
</code></pre>

<p>Do not use the if statement outside the block statement.</p>

CC BY-SA 3.0
2016-08-31T11:34:48.867Z
2016-08-31T11:34:48.867Z
Stephan
<p>This is a known issue with Twig’s ‘defined’ test - it’s not very reliable when it comes to object properties. We plan on looking further into it at some point and coming up with a formal test case that reproduces the issue, plus a bug fix. Just haven’t gotten around to it yet.</p>

<p>In the meantime, rather than testing if a field is defined, check the entry type:</p>



<pre class="lang-twig prettyprint-override"><code>{% if e.type == 'news' %}
</code></pre>

<p>If you want to check multiple entry/block types at once, you can use the <code>in</code> operator:</p>

<pre class="lang-twig prettyprint-override"><code>{% if e.type.handle in ['news', 'blog'] %}
</code></pre>

CC BY-SA 3.0
2015-02-13T01:47:04.193Z
Is this still true? I have an environment where a field is assigned to an entry type, and another environment where it isn't—so the entry type check won't solve this. (Nevermind that my situation is questionable.)
Matt Stein
CC BY-SA 3.0
2015-02-18T14:28:06.947Z
@MattStein Yeah. I recently spent some time trying to look into it again but Twig basically just assumes something actually is defined if it can’t be determined. In your case you would just need to add an additional check in the conditional for the environment. (You can give each environment config a custom `'env'` key set and check with `craft.config.env`.)
Brandon Kelly
CC BY-SA 3.0
2015-02-18T15:38:49.687Z
@BrandonKelly So to Twig, a falling tree makes a sound no matter what. Thanks for the update and environment-check approach!
Matt Stein
CC BY-SA 3.0
2014-08-22T18:02:03.353Z
2014-08-22T18:02:03.353Z
Brandon Kelly
<p>I am trying to code defensively and check whether a field exists before accessing it:</p>

<pre><code>{% if e.someField is defined %} {{e.someField}} {% endif %}
</code></pre>

<p>And I get a CException</p>

<blockquote>
  <p>Craft\EntryModel and its behaviors do not have a method or closure named "someField".</p>
</blockquote>

<p>Because <a href="http://twig.sensiolabs.org/doc/templates.html#test-operator">is</a> <a href="http://twig.sensiolabs.org/doc/tests/defined.html">defined</a> is always returning <code>true</code>.</p>

<p>Any clue what's wrong?</p>

<templating>
Twig "is defined" always returning true
# Twig "is defined" always returning true

(Asked by: username_0 on 2014-08-22)

I am trying to code defensively and check whether a field exists before accessing it:
{% if e.someField is defined %} {{e.someField}} {% endif %}

And I get a CException

Craft\EntryModel and its behaviors do not have a method or closure named "someField".

Because is defined is always returning true.
Any clue what's wrong?

**Tags:** templating


---

## 5 answers

### Answer by username_9 on 2014-08-22. Score: 10 | Accepted answer

This is a known issue with Twig’s ‘defined’ test - it’s not very reliable when it comes to object properties. We plan on looking further into it at some point and coming up with a formal test case that reproduces the issue, plus a bug fix. Just haven’t gotten around to it yet.
In the meantime, rather than testing if a field is defined, check the entry type:
{% if e.type == 'news' %}

If you want to check multiple entry/block types at once, you can use the in operator:
{% if e.type.handle in ['news', 'blog'] %}

> **Comments:**
> **username_10**: Is this still true? I have an environment where a field is assigned to an entry type, and another environment where it isn't—so the entry type check won't solve this. (Nevermind that my situation is questionable.)  
> **username_9**: @MattStein Yeah. I recently spent some time trying to look into it again but Twig basically just assumes something actually is defined if it can’t be determined. In your case you would just need to add an additional check in the conditional for the environment. (You can give each environment config a custom `'env'` key set and check with `craft.config.env`.)  
> **username_10**: @BrandonKelly So to Twig, a falling tree makes a sound no matter what. Thanks for the update and environment-check approach!  

---

### Answer by username_1 on 2015-10-24. Score: 17

I believe I have a workaround and can (roughly) explain what's going on here.
First, the workaround:
Use array syntax to test the existence of your custom fields instead of object syntax.
{# This works #}
{% if entry['someField'] is defined %} ... {% endif %}

Using array syntax for your conditional will result as true if your field does exist and false if it does not. Using object syntax results in false positives where the conditional always returns true even if a field doesn't exist:
{# FALSE POSITIVES: These return true if a field doesn't exist #}

{% if entry.someField is defined %} ... {% endif %}
{% if attribute(entry, 'someField') is defined %} ... {% endif %}

I believe the false positive occurs using object syntax when the object has or is extending another object that uses a __call() method. Twig will test to see if it can find an attribute or a method.  In the case it can't find an attribute on an object, it will look for a method.  And if it can't find a method on the object, it will check for the existence of a __call() method and if the _call() method exists it returns true, creating the undesired result of also returning true for any variable that doesn't exist on an object that uses a __call() method.
I haven't dug into the code, but it seems that using the array syntax doesn't trigger a search for a potential method associated with the __call() behavior.

A couple related articles can be found on Straight Up Craft:

How to check if a variable or value exists using Twig
Testing if something exists: is defined, length, is not null, is not empty

> **Comments:**
> **username_2**: This should go into the official documentation! ... I just dumped several hours into researching this odd behaviour :(  
> **username_3**: Sweet, that resolves it. Thanks for sharing!  
> **username_5**: 2019 and this is still an issue - and this appears to still be a work-around. Thanks!  
> **username_4**: This had me flummoxed, thank you!  

---

### Answer by username_6 on 2015-03-04. Score: 1

I was able to resolve this issue by creating a custom plugin that uses a service and template variables. The service will accept the content object and field name. You can reference how to write a conditional to check if the field is set (http://buildwithcraft.com/classreference/models/BaseElementModel#getFieldValue-detail). The service is then used in the template variables and will return true or false based on if the field is set.
Craft Template Twig Example
{{ (craft.pluginName.isFieldDefined(e, 'someField') ? e.someField : false) }}

Sorry, I can't post a full code example.


---

### Answer by username_7 on 2020-08-21. Score: 1

I came across this while trying to check if object has method. I found out that is defined always returns true and some other options would return always null (even if the method existed) so I ended up writing a twig extension (which was faster than trying to solve the problem):
/**
 * @param object $entity
 * @param string $method
 *
 * @return bool
 */
public function twig_method_exists($entity, string $method): bool
{
    if (!is_object($entity)) {
        throw new InvalidArgumentException('Given entity is not of type object, got: '.get_class($entity));
    }

    if (empty($method)) {
        throw new InvalidArgumentException('Method name empty');
    }

    return method_exists($entity, $method);
}


And i use it like this in the twig
{% if method_exists(entity, 'getCreatedBy') %}
    ({{ entity.createdBy.name }})
{% endif %}


---

### Answer by username_8 on 2016-08-31. Score: 0

I had a similar issue when using an if statement to define a block element. The correct way doing this will be following:
{% block metaOgImage %}
  {% if og.image is defined %}
   
  {% endif %}
{% endblock %}

Do not use the if statement outside the block statement.


---

