The Jira form smart value that writes nothing and reports success
Gabriela Perdum
Author
18 min readAugust 3, 2026
Key takeaways
Two unrelated features are called Forms. These smart values only reach advanced forms, the ProForma lineage. Atlassian stated on JRACLOUD-98636 that Jira Software projects do not support advanced forms at all, and closed it Won't Fix.
The root smart value is forms, plural. A rule written as {{form.last.key}} resolves to nothing, and the run still reports success. The Edit action does not skip the field, it submits an empty value, so on a field that already held something this can wipe it.
A dropdown is a choice field, so the answer holds choice IDs and not text. You have to ask for {{label}}, because the label is never stored on the answer. It lives in the form design.
Six question types are choice fields: Radio buttons, Checkboxes, Dropdown, Multiselect dropdown, Cascading dropdown and Assets. Asking for .id where you meant .label gives you a populated field with the wrong value in it.
Form triggers cannot be configured globally. A rule built in global automation never sees a form, so no smart value fix will save it.
Give every form smart value a default: {{forms.last.key.label|"NO ANSWER"}}. A field reading NO ANSWER tells you the smart value broke. An empty field tells you nothing.
…I have a submission form on a jira space that creates a new initiative. On that form is a field "Loyalty Origin Team" which is a dropdown. What I want to do is -> When the form is submitted, have the automation go look at the Loyalty Origin Team" response and drop it in to a short text field (called Team Name). That's it. I have given the form field a key (loyalty-origin), and tried pulling it both directly and through a smart value. My automation runs, it doesn't give me any errors, but it isn't actually changing the work item.
He then guessed at three causes: the rule running too fast to see the form, the dropdown text being too long for a short text field, and the dropdown answer not counting as text. The third guess is close to right for the wrong reason. The first two are not it.
Two things were wrong, both visible in the rule itself, neither visible in the audit log. That last part is the whole problem, so start there.
Note
Everything below was re-read from Atlassian's own documentation, OpenAPI specification and public issue tracker on 3 August 2026, and the REST behaviour was exercised the same day against a live Jira Cloud site. Ticket statuses and vote counts move, so I have dated the ones I quote. Where I could not verify something I have said so in the section it belongs to rather than saving it for the end.
Why nothing errors
An unresolvable smart value in Jira Automation is not an error. Atlassian's smart values documentation puts it without hedging: "If a field or value doesn't exist, it will return an empty value." So a rule that reads a form answer into a variable, gets nothing, and hands that nothing to an Edit action has done what it was told. It created a variable, it performed an edit, it finished, and it reports the run as successful.
The next step is where I would have got this wrong myself, so be careful with it. The Edit action does not skip the field. It submits an empty value, and what that does depends on the field type. For the asker it was invisible, because Team Name was a new field that was already empty. On a field that already holds something, the same rule can wipe it. That is not universal either: Atlassian closed AUTO-2067 as Not a bug precisely because the parent field does not clear when an Edit action sets it empty, and the rule still reports success. So neither "it clears everything" nor "nothing changes" is safe as a flat statement. Assume a write happened and go and look at the work item.
Either way the failure hides exactly where you would look for it. Form answers live in their own key namespace, separate from Jira fields, and a mistake in that namespace has no failure mode. A typo in a Jira field name gives you something to read. A typo in a form key gives you a clean run and an empty field.
The guard is a default value, documented on that same page and used by almost nobody: "You can specify a default value to prevent this… you can print Hello world using {{invalid reference|"Hello world"}}." Applied here that is {{forms.last.loyalty-origin.label|"NO ANSWER"}}. The point is not the fallback text. It is that a field reading NO ANSWER tells you the smart value is broken, and an empty field tells you nothing at all.
Before any of the syntax: which Forms do you have?
This is the check that decides whether the rest of this article is your fix or a waste of your afternoon, and it is the one nothing in the smart values documentation tells you to make.
"Forms" in Jira Cloud means two unrelated features that share a name.
One is advanced forms, the old ProForma product Atlassian acquired. A form is an object that gets attached to a work item, has states, can be submitted and reopened, and has a REST API. This is the one automation understands. The API's own OpenAPI title is still, literally, "ProForma Forms RESTful API".
The other is the newer forms in Jira for software and business spaces. That form creates a work item when somebody submits it. There is no persistent form object hanging off the work item afterwards, no form states, and no REST API.
Every smart value in this article belongs to the first one. Atlassian says so on their own tracker, in the plainest terms anyone has managed. On JRACLOUD-98636, a bug raised on 19 June 2026 because the forms REST API returned an empty response for Jira Software forms, Simon Taylor of Atlassian replied on 23 June:
Understand the confusion here, the documentation is worded poorly. The REST API is only available to advanced forms which are available only in JSM projects. JSW projects do not support advanced forms and therefore do not provide a REST API.
That bug is Closed as Won't Fix. The trigger side has its own request, AUTO-1661, which opens: "At present, Jira automation lacks the Form Submitted trigger for Jira Software (JSW) projects; this functionality is exclusively available for Jira Service Management (JSM) projects." It has been Gathering Interest since 27 January 2025 and had 9 votes when I read it on 3 August 2026.
The clearest statement of the split, and the one to send anybody who argues about it, is the Jira Cloud team's own update panel on JRACLOUD-85492 dated 30 January 2025:
The forms available in service projects will not be made available for business or software projects. If you already have access to the forms in JSM in your software and business projects today, these will remain untouched.
That second sentence is the one that matters for this article, and it is why the thread below is not a contradiction. Sites that had ProForma before the split kept advanced forms in their business and software spaces. Those still work. Nobody new is getting them.
The documentation Simon Taylor called poorly worded is still live and still says the opposite. The forms REST API introduction reads: "Forms in all editions of Jira Cloud are supported, including Jira Service Management, Jira Software, and Jira Work Management. ProForma is referred to as Advanced forms in Jira Work Management, with the forms REST API working with this type only." The first sentence invites you in and the second quietly takes it back, which is how people end up on that tracker in the first place.
Warning
If your form lives in a Jira software or business space and it is a native Jira form rather than a legacy advanced form, {{forms.last.…}} will not work for you and no amount of fixing the syntax will change that. The Form submitted trigger either will not appear or will offer you an empty list of forms.
The route that does work there is a Work item created trigger with a condition, and the hook to condition on is documented: submitting a native Jira form adds two labels to the work item it creates, Form and Form-<unique-form-id>. The second one identifies which form it came from, which is what you want. Be aware that people are asking for those labels to stop appearing (JRACLOUD-92173, Gathering Interest, 27 votes on 3 August 2026), so it is a documented hook rather than a permanent one.
The thread this article started from was an advanced form on a business space, which is a real configuration for anyone who had ProForma before the split, and that is why the fix below worked for him. If you are on a service space, all of it applies to you directly.
Defect one: the root is plural
The root smart value is forms. Not form.
The flow he posted showed {{form.last.loyalty-origin}} in a Create variable step. Singular. That resolves to nothing, the variable comes out empty, and the Edit action writes an empty string into Team Name without complaining.
Atlassian's wording, on the page that documents all of this, Access smart values for forms and form fields, is that you access submitted forms "by using {{forms}} to format the value of forms in a list", and every worked example in the field-type sections is built on the plural root. Their own is {{forms.last.onboarding-notes}} as a comment body.
One character. That is genuinely the difference between the rule working and the rule doing nothing forever.
While you are looking at the key, note that hyphens are fine. onboarding-notes is Atlassian's own example, so loyalty-origin was never the problem, and nobody should be sent chasing key syntax. What does matter is case: "Field keys are case-sensitive so need to be entered correctly. This also includes any spaces." A key of Due date is not due date and is not Duedate.
Defect two: a dropdown is not text
Fixing the plural on its own would still not have finished the job, because a dropdown answer is not a string.
Atlassian splits form questions into groups, and a dropdown sits in the group they call choice fields. Those use the list smart values, and the instruction is explicit: "To retrieve the id of a selected choice use {{id}} and to retrieve the label of a selected choice use {{label}}." The worked example is a field keyed Location with 'Sydney' selected, where {{forms.last.Location.label}} returns 'Sydney'.
Six question types are choice fields:
Question type
Choice field
Radio buttons
yes
Checkboxes
yes
Dropdown
yes
Multiselect dropdown
yes
Cascading dropdown
yes
Assets
yes
7 rows × 2 columnsHeader row enabled
So the working string for the thread's rule was:
text
1{{forms.last.loyalty-origin.label}}
Plural root, and .label on the end. That is what he needed, and it is what fixed it.
Why .label exists, which the docs never explain
The documentation tells you to add .label. It does not tell you why, and the why is worth two minutes because it makes the whole family of these bugs predictable.
The answer stored against a choice question does not contain the words you see on screen. Atlassian's own OpenAPI specification for the Forms REST API defines a form answer's choices property as, verbatim, "IDs of choices that have been selected." Text answers get a text property described as "Contains an answer in free text format." Those are different properties holding different things.
The labels live somewhere else entirely, in the form's design. I built a form on a live Jira Cloud site to look at the split directly. Creating a dropdown question through the API and reading the design back gives you this, inside the form's design object alongside its conditions, layout, sections and settings:
The design holds the id-and-label pairs. The answer holds the ids. .label is a lookup from one into the other, and .id is what you use when you want the stable identifier instead of the display text, which is the better choice if somebody might rename a dropdown option later.
That also tells you what a bare {{forms.last.someChoiceField}} is: a reference to a list object, not to a word. It is not that the value is too long for a short text field, which was the asker's second guess. It is that there is no text there to be too long.
The type codes are worth knowing if you ever script against forms. The API enum runs at attachment, cc cascading dropdown, cd dropdown, cl multiselect dropdown, cm checkboxes, cs radio buttons, ob assets object/s, da date, dt date and time, no number, rt paragraph, te email, tl long text, pg legacy paragraph, ts short text, tu URL, ti time, um multiple users, us single user. Nineteen types.
The specification does not group them. That grouping into text, choice, date and the rest exists only on the smart values page, so mapping one onto the other is my own reading rather than something either document states. Done that way, the six codes whose API names correspond to the six choice fields are cs, cm, cd, cl, cc and ob, which covers the published list with nothing left over on either side.
The whole mapping, in one place
This is the part I wanted written down somewhere findable. Atlassian's page carries it, but that page sits in the Jira Service Management documentation tree, which is an awkward place to go looking if your form is on a Jira business or software space.
That location is not an accident, and after the section above you know why: this is the advanced forms feature, and Atlassian's position is that it belongs to service management. The reason it still matters outside JSM is the legacy case. The thread this article started from was an advanced form on a business space, and {{forms.last.<key>.label}} is what fixed it there.
Group
Types
Example
Text
Short text, Long text, Paragraph, Email, URL
{{forms.last.Summary}} returns 'Jane Doe'
Choice
Radio buttons, Checkboxes, Dropdown, Multiselect dropdown, Cascading dropdown, Assets
{{forms.last.Location.label}} returns 'Sydney'
Date
Date, Date & Time, Time
{{forms.last.Due date.fullDate}} returns 'Wednesday, October 1, 2024'
Number
Number
{{forms.last.Invoice}}, and see the note below on asCurrency
{{forms.last.Upload resume.name}} returns 'Jane Doe CV'
7 rows × 3 columnsHeader row enabled
Attachments behave like choice fields in that they also take {{id}} and {{name}}.
Three caveats on that table, because it is the bit people will copy.
The Number row is the one place where I have contradicted the documentation. The page advertises {{forms.last.Invoice.asCurrency}} returning '$100', and Bruno Altenhofen of Atlassian says in the article linked above: "Please be aware that, unfortunately, the {{.asCurrency}} feature is not currently supported in Forms." An Atlassian Team member correcting an Atlassian doc is as good as this gets, so use the bare value and format it yourself.
Atlassian gives exactly one worked choice-field example, Location with .label. Cascading dropdown is in the choice list and its answer has two levels, and nothing I could find shows how .label behaves there. Treat that one as untested rather than as covered by the row.
Assets in that list is not a plain question type. It is Jira Service Management only and it is plan-gated, so a table row implying parity with Dropdown is flattering it.
Two things that make all of the above irrelevant
Before you spend an afternoon on smart value syntax, check these, because either one makes the syntax question moot.
The first is that smart values on forms are gated on the trigger. Atlassian's page opens with it: "Only smart values on forms that use the form submitted trigger can be accessed." If your rule is triggered by work item created, or a transition, or a schedule, {{forms.last.…}} has nothing to resolve against no matter how correctly you spell it.
The second is scope, and it is the one that catches people who administer at site level. From the automation triggers documentation, including Atlassian's own typo: "Form triggers are only space-specific and can't be configured in globally." A rule you built in global automation will never see a form. There is no smart value that fixes that, and no amount of debugging the string will tell you it is the problem.
There is a third thing on the Form submitted trigger that is not a gotcha so much as a sharp edge. You can select any number of forms on it, and the selection changes the semantics: no forms selected means the rule runs when any form is submitted, one form selected means it runs for that form, and if you select several then "the flow will only run when all of the selected forms on a work item are submitted." Multi-select is an AND, not an OR. If you picked three forms expecting three independent triggers, you built one rule that waits for all three.
The route the documentation buries, and then contradicts
That opening sentence about needing the form submitted trigger is not the whole story, and the same page proves it. Further down there is a section titled "Access smart values without using the Forms submitted trigger", and it hands you a different root: "You can also access any forms on a work item by using {{issue.forms.<UUID>}} and referring to automation lists smart values."
The field key goes on the end of that, which the page shows only through its example rather than as syntax. Their example is a manual trigger from a work item with a comment body of {{issue.forms.f7142b07-d3a4-4522-a7e4-8799d526e0a6.payroll-salary}}.
Do not copy that example's shape. The UUID root returns a list, which the same page says outright: "These will be grouped by their Universally Unique Identifiers (UUIDs) and be returned as a list". Atlassian's own example then indexes into that list with nothing at all. Bruno Altenhofen of Atlassian spells out the missing piece in Using Forms Smart Values: "Since {{issue.forms.formTemplateID}} gives you a list, you can access a specific form using {{issue.forms.formTemplateID.get(0)}}" or .last. So the shape you want is:
text
1{{issue.forms.<UUID>.last.<field key>}}
Both angle-bracket parts there are placeholders, not literals. Read the top line as scoping {{forms}} rather than as scoping form access in general, and the page stops contradicting itself. That is my reading of the two statements, not something the page says about itself.
The catch is the UUID. The documentation tells you to get it "from either the Forms REST APIs 'Get project form index', or by inspecting elements on the Forms landing page and accessing the UUID via the Network tab", and then leaves you there. The Network tab route is miserable. The API route is one call, and I checked that it works with an ordinary Atlassian API token rather than an OAuth app:
bash
1CLOUD_ID=$(curl-s https://your-site.atlassian.net/_edge/tenant_info | python3 -c 'import json,sys; print(json.load(sys.stdin)["cloudId"])')2PROJECT_ID=DFD # numeric id or project key, UPPERCASE3JIRA_API_TOKEN=your-api-token
45curl-s-u"you@example.com:$JIRA_API_TOKEN"\6-H"Accept: application/json"\7"https://api.atlassian.com/jira/forms/cloud/$CLOUD_ID/project/$PROJECT_ID/form"
_edge/tenant_info needs no authentication, so that first line works before you have sorted out any credentials. The form index call takes an ordinary API token, not an OAuth app, and no experimental-API header.
PROJECT_ID takes the numeric project id or the project key, and the key has to be uppercase. In an article about case sensitivity that is worth its own line: DFD returns the index, dfd returns 400 Cannot parse parameter projectIdOrKey as JiraProjectIdOrKey.
The response is the form index, and the id on each entry is the UUID:
A project with no advanced forms returns []. So does a project where advanced forms are not a feature at all, and nothing in the response distinguishes them. That is exactly the confusion behind JRACLOUD-98636: the reporter created a form in Jira Software, called this endpoint, got an empty 200, and called the same endpoint against JSM where it returned the form properly. Read [] as "nothing here that this API can see", never as "right project, nothing in it yet".
I also hit something on my own test site that I cannot reconcile with Atlassian's statement, so I am going to report it rather than explain it. Both service management projects there returned 404 RESOURCE_NOT_FOUND on the index call, body "You do not have permission to access this resource, or it was not found." That is the opposite polarity to the ticket, where JSM is the case that works. It is not permissions and it is not emptiness, and I checked that on the same project rather than on a convenient neighbour: the account holds Browse projects there, creating a template on that same project returns 200 and a UUID, the index still returns 404 with that form present, fetching the new form by its own id also returns 404, and deleting it returns 200 while deleting it again returns a different, object-aware 404 carrying FORM_TEMPLATE_NOT_FOUND. Writes resolve the project. Only the read index refuses.
Two service projects against fifteen other projects on one site is a measurement, not a mechanism. Something about that tenant or those projects is doing it and I do not know what. Run the call on your own site before you build anything on it, and treat a 404 here as a reason to go and look rather than as a diagnosis.
On the permissions themselves the reference is ambiguous and I could not settle it. All three write endpoints are annotated "Administer Jira project permission", which runs two different Jira permissions together: ADMINISTER is the global one named Administer Jira, ADMINISTER_PROJECTS is the project one named Administer Projects. The account I used reports the global permission as true and Administer Projects on that project as false, and its creates and deletes succeeded anyway. The wording points one way, the behaviour points the other, and I had no second account to test the converse. Unresolved, and flagged rather than guessed.
There are two UUIDs, and only one of them is in the index
The id in the project form index identifies the form template. A form attached to a work item has its own separate id. Attach a template to an issue and the issue's form index comes back with a different id and a nested formTemplate.id pointing back at the template.
Atlassian's example for {{issue.forms.<UUID>}} describes multiple copies of one form on a work item being grouped, with the most recent winning, which is template-shaped behaviour. That is why the project index is the id I would reach for, and it is the one their own instructions send you to. It is also why the Network tab route is worth avoiding: what you see there while poking at a work item is plausibly the instance id, and the two are indistinguishable by looking at them.
I confirmed the index call and the UUID it returns. I did not confirm that {{issue.forms.<UUID>.<key>}} resolves inside a live rule, because creating automation rules needs the UI and the browser session I would have used had expired. No automation REST endpoint accepts an API token, so there is no way around that from a script. Treat the endpoint as measured and the smart value itself as documented.
If you do try it, remember the failure mode from the top of this article. Picking the wrong UUID gives you an empty field, not a red error. So look at the value before you point it at a field, and there is a better way to do that than the one most people reach for. Wrap it in {{#debug}}: "Surrounding any smart value with debug, allows the smart value to be processed as normal and also prints the value in the audit log to provide more contextual information." That prints into the audit log without adding a step to the rule, which the Log action does require.
Check the key exists at all
There is a smaller trap underneath both defects. In the API specification, questionKey is described as "An optional unique identifier for this question on a form." Optional, and blank by default. A question with no key cannot be reached by the {{forms.last.<key>}} shorthand at all, because there is no name to address it by, and older forms built before field keys existed are full of these.
That is not a dead end, which is the part I nearly got wrong. Question IDs are the documented way in. From the same Atlassian article: "To access fields in existing forms that lack the new field keys, you can use their IDs instead using: {{issue.forms.formTemplateID.get(x).questionID}}. IDs are always available; they are generated when a new field is added to a form, are unique, and can be used even if field keys are present." Their worked example is {{issue.forms.d6d3a06b-44c4-46aa-b58c-9a46743898dc.get(0).88}}, where 88 is the question ID.
Note which root that hangs off. The ID route is documented on {{issue.forms.<UUID>}} and I have not seen it shown on {{forms.last…}} under the Form submitted trigger. So a keyless question is reachable, but reaching it may mean switching roots. Setting a key is still the better answer if the form is yours to edit.
So the order of checks that saves time is: does the question have a key, is the root plural, and is it a choice field that needs .label. Doing it in that order means you never debug a string that was never going to resolve.
Where this stops being a syntax problem
The reason this specific bug costs people days rather than minutes is that the failure is indistinguishable from success everywhere the platform reports on itself. The rule ran. The action fired. The audit log is green. The only evidence anything went wrong is a field that a human eventually reads, usually well downstream, often after the work item has moved through two or three statuses on the strength of data nobody checked.
Validators catch less of this than you would hope, and the reason is not that Jira's validators are weak. Company-managed workflows do ship a Regular Expression Check alongside Field Required, so shape can be enforced. The problem is that this bug has a variant which produces a field that is populated and correctly shaped and still wrong: ask for .id where you meant .label and Team Name receives the choice's identifier instead of the words somebody picked. In the form I built above that is the difference between Acquisition and 2. It satisfies a required check, it satisfies a regex expecting a short token, it reads as working on a board, and it is wrong. Nothing native is positioned to know that 2 was supposed to be a team name.
Worth knowing if you are on a team-managed project: there is no field-required validator there at all. That has been JRACLOUD-87579 since 2021, Gathering Interest, 60 votes on 3 August 2026.
Tip
We built CogniRunner for exactly that gap: workflow validators, conditions and post-functions that judge what a field actually says before a transition is allowed, rather than only that something is in it. Full disclosure, it is one of ours.
The same shape, one thread over
A month earlier somebody else asked whether they could enforce a naming convention on the summary using Forms, so that new work items inherited the prefix of their parent epic. The answer there was also that the form cannot do it, and that automation has to assemble the value after the fact.
That is the same lesson arriving from a different direction, and it survives the split between the two form products. Whichever kind you have, the form collects answers. It does not enforce anything about the resulting work item, and it does not tell you when something went looking for an answer that was not there. Everything that turns what somebody typed into a Jira field the way you want it is automation, which means most of these problems are smart value problems, and smart value problems fail quietly by design.
What I still do not have is a way to see what a rule would write without letting it write. {{#debug}} prints the value as the rule processes it, which is the best tool available, but the Edit action still fires behind it. So on a field that already holds something, you find out what the rule got wrong by watching it damage the thing. If somebody has a genuine dry run for automation rules, I would like to hear about it.