Here are the steps to reproduce. Pretty sure this may be a bug:
This not messing up, as it is a text field, filled or not
Automation actions using a form field that is always on the form (based on text) it will copy the value in the field.
If there is no information on the field the field still exists, but just with no information (null).
Smart value "exists"
{{exists(smartValue)}} returns true or null
{{exists("string")}} returns true or null
So it returns what is in the field or empty, it will no fail.
I wasn't very clear... for the text field, if I do NOT set the default value and the user does not enter anything when completing the form, it comes back as 'false'. If the user does enter something in, then it comes back as 'true', which is what I would expect.
If I DO set the default value, then it comes back as 'true' -- again, what I would expect.
If I delete what I put into the default value (so it's back like it was before), instead of coming back as 'false', it still comes back as 'true'.
If I delete the form component, then put a new one in, and don't touch the default value at all, then it comes back as 'false' (if the user doesn't put anything in the field).
It's as if once that default value is used, then it will ALWAYS come back as 'true', even after the value is deleted and the user leaves it blank.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I just explained this, this is not how this works on a text field.
It will always come back with the input value or as NULL (blank) if no input is done.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
... which is exactly why I think there's a bug. If there is no input (i.e. the default value was there but was then deleted), it comes back as having an input value -- not null like you're saying it should. I can test this again, but this is the behavior I observed when running around in circles trying to figure out why it was not working how I expected.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Then you need to use a smart condition block in your automation, this is you want a real condition.
Use a {{smart values}} condition.
Value to check: {{forms.last.my-field-name.trim}}, select your option (options in documentation) and your value to check towards.
This is not a Bug you base your action on text input in a field. The exist means is the field on the form, empty or not.
The smart value options you are referring to are to be used to print outputs based on conditional logic, not actual conditions if the field has a value yes or no, then you need to use a {{smart values}} condition in your automation.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello @DOUGLAS THOMPSON and @Marc -Devoteam- , I read through this exchange and decided to settle it with a clean test rather than add another opinion, so here is what I actually did and found.
Setup: fresh text field, key ghosttest, no automation if/else (avoided a syntax mismatch on this instance), just a direct print of the smart value:
EXISTS RESULT: {{exists(forms.last.ghosttest.trim)}}
RAW VALUE: [{{forms.last.ghosttest.trim}}]
The test sequence, matching your matrix, Douglas:
exists false, raw empty. Expected.HELLO, left untouched, field shows it correctly.ghosttest, default box empty on creation (confirmed it does not inherit anything from the deleted field), submitted blank.exists() directly on that submission: EXISTS RESULT: false, RAW VALUE: [].No ghost value at any point. The smart value engine returned exactly what it should on a genuinely empty field, whether the emptiness came from a cleared default or a freshly recreated field.
So on my instance, Marc's explanation holds up under a real test, not just in principle. exists() reflects whatever is actually stored, with no memory of a prior default.
Douglas, since your result differs from a clean reproduction, one thing worth checking that could explain it: are you testing exists() on the exact same expression path I used (forms.last.<key>.trim), or is there a different smart value in play, forms.first, a different form on the same issue, or the field referenced without .trim? A trailing space or a stale forms context (referencing an older submission rather than forms.last) would produce exactly the symptom you described. If you can share your rule's actual smart value line, that would likely surface the difference in seconds.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I truly appreciate the feedback and input.
Mine is just like yours Sami(forms.last.field-key.trim)
For your #3, after deleting the default value and submitting blank, I would expect the result to be 'false', but it's 'true'. It seems there is no way to get the field back to the original 'false' test result without deleting the field entirely and recreating it.
What I would like to do with a form is put in default values, run some tests, then remove the default values so that 'exists' reverts to seeing the field as 'false'. Instead, here's what happens:
+----------------------------+--------------------+----------------+
| Form Field Default Value | Exists on No Value | Expected Value |
| Set | | |
+----------------------------+--------------------+----------------+
| No | false | false |
| Yes | true | true |
| No (text deleted) | true | false |
+----------------------------+--------------------+----------------+
And maybe I should just be doing my automation differently and there's something better to use than 'exists'. I just thought by deleting the default value, it would revert back to the same 'false' condition as before when the field was first created. As mentioned, there seems to be no way to ever get 'exists' to be false again without destroying the field and recreating it.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@DOUGLAS THOMPSON you were right, and I owe you and the thread a correction. I reran this properly and reproduced your row 3 exactly.
First, the correction. My earlier "clean" test was measuring nothing: I had the rule on the Issue created trigger, and per Atlassian's own documentation, forms.last.* smart values are only populated when the rule uses the Form submitted trigger. Every result I posted yesterday came from an empty namespace, which is why it all read false / [] regardless of the field. My apologies for the confident-sounding wrong answer.
The real test, on the Form submitted trigger:
HELLO set, submitted pre-filled: exists true, raw [HELLO] (control, works)exists true, raw [], your row 3, reproducedWhy it happens: clearing the text out of a default value box leaves the field holding an empty string, not a null. exists() tests presence, not content, so an empty string counts as present. A field that never had a default holds null, which is why a freshly recreated field returns false. You did not misread anything; exists() is the wrong tool for this question.
The fix is to test for content instead of presence. Replace the exists() check with an emptiness check on the trimmed value:
{{#if(not(equals(forms.last.field-key.trim, "")))}}Field Name: {{forms.last.field-key.trim}}{{/}}
Tested on my side in three cases: a real default value fires, a cleared default prints nothing, and a value the user types into a no-default field fires. That treats "" and null identically and gives you the behaviour you wanted all along, with no need to delete and recreate fields.
@Marc -Devoteam- your point that the field still exists with no information was correct in principle; the twist is that "no information" after clearing a default is an empty string rather than null, and exists() distinguishes the two. Good thread, and a genuinely useful gotcha for anyone mixing defaults with automation conditions.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you @Sami Shaik and @Marc -Devoteam- . I will do some testing and transition away from using "exists".
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Finished testing... looked at 'exists' and 'equals'. Unfortunately the following doesn't work by itself for all cases:
{{#if(not(equals(forms.last.field-key.trim, "")))}}Result Here{{/}}This doesn't work for a 'null' field (i.e. never had any value there). The only way I was able to get it consistent for 'null', 'String Value', and 'Empty String' was to use 2 conditions. Here's a truth table with some examples. It should only be 'true' when there is a string value, otherwise it should be false (bold/underline means the condition matches what I need; italicized means it does not meet my needs):
| Condition | null | String Value | Empty String |
| {{exists(forms.last.field-key.trim)}} | false | true | true |
| {{not(equals(forms.last.field-key.trim, ""))}} | true | true | false |
| {{not(equals(forms.last.field-key.trim, null))}} | false | true | true |
| {{and(not(equals(forms.last.field-key, null)), not(equals(forms.last.field-key.trim, "")))}} | false | true | false |
| {{and(exists(forms.last.field-key), not(equals(forms.last.field-key.trim, "")))}} | false | true | false |
The only way I know of to truly identify if a field has a non-null, non-empty value is to combine 2 conditions together. Personally I favor the 'exists' and 'equals' combo.
Whew! That took way longer than it should have... thanks again for the feedback!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@DOUGLAS THOMPSON this is a great piece of testing and your conclusion is the right one. The two-condition combo is the correct general-purpose check: exists() rules out the null case (field never populated), and the not-empty comparison rules out the empty-string case (default set then cleared), which was the exact behaviour in your original report. Neither alone covers both, as your table shows.
For anyone landing on this thread later: use Douglas's combined condition, swap in your own field key, and keep the rule on the Form submitted trigger, since the forms.last namespace only populates there.
Thanks for pushing on this until the logic was actually right. This thread ended up far more useful because you did.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.