RFC-146: Conditional execution for Jira workflow post functions

RFCs are a way for Atlassian to share what we’re working on with our valued developer community.

It’s a document for building shared understanding of a topic. It expresses a technical solution, but can also communicate how it should be built or even document standards. The most important aspect of an RFC is that a written specification facilitates feedback and drives consensus. It is not a tool for approving or committing to ideas, but more so a collaborative practice to shape an idea and to find serious flaws early.

Please respect our community guidelines: keep it welcoming and safe by commenting on the idea not the people (especially the author); keep it tidy by keeping on topic; empower the community by keeping constructive. Thanks!

Project Summary

  • Publish: 15 September, 2026

  • Discuss: 16 September, 2026 - 2 October, 2026

  • Resolve: 12 October, 2026

Today, Jira workflow post functions run unconditionally. If a post function is configured on a transition, it fires every time that transition executes.

We will add an optional Jira Expression to native post functions so a workflow admin can say “only run this action when…” without restructuring the workflow. Jira will evaluate the expression during the transition before the post function executes. If it evaluates to false, the post function does not run.

We plan to release this to Beta / EAP participants around late October or early November 2026. Initial rollout will focus on native post functions such as system:update-field, system:copy-value-from-other-field, and system:trigger-agent, with support through our public workflow APIs.

Our intent is to expand native conditional execution to Forge and Connect post functions, and potentially validators as well in the future. Before doing so, we want to gather feedback from partners and developers to gather feedback on extension and execution needs that can best serve your apps.

This RFC is relevant if your app provides workflow post functions, conditions, or validators, or if it offers its own mechanism for conditionally gating workflow behavior.

Problem

To add conditional behavior to a post function today, a workflow admin must express the condition in the workflow’s structure rather than the rule. In practice that means one of:

  • splitting one logical transition into several near-identical transitions, each with a different condition and set of post functions;

  • adding intermediate statuses purely to route work items to the right actions;

  • using a Marketplace app that offers gating on its post functions.

The result is workflows that are much larger than the process they model, with the same action configured in several places and no single place to change it.

Workflow agentification makes this more pressing. In 2025 we introduced the Trigger Agent post function, which lets an admin invoke an agent when a work item is created or transitioned. Uptake has been steady, and unlike Update Field, an agent invocation incurs customer cost in tokens and credits. Running one on every transition execution, when the admin only wants it for bugs or when the ticket has certain fields filled, wastes billable resources. We’ve seen admins build elaborate transition graphs solely to gate an agent.

Proposed Solution

A post function may include an optional conditionExpression parameter. Jira evaluates it during the transition, immediately before the post function would execute. If it evaluates to true, the function runs. If it evaluates to false, the function is skipped and the transition proceeds normally.

If the expression errors, fails validation, or cannot be evaluated, we treat the result as false and do not run the post function.

For example, this configuration sets Priority to High only when the work item is a Bug.

  • ruleKey identifies the native post function being configured.

  • parameters holds that function’s settings, as it does today.

  • conditionExpression is the gate.

{
  "id": "fee457e7-bdbe-4073-aebb-b067185d224d",
  "ruleKey": "system:update-field",
  "parameters": {
    "field": "priority",
    "value": "High",
    "conditionExpression": "{\"expression\":\"issue.issueType.name == \\\"Bug\\\"\"}"
  }
}

Why the expression is a JSON-encoded object rather than a bare string

conditionExpression wraps the expression in a JSON object intentionally: we expect to add sibling properties over time (a human-readable description, configuration metadata referencable within the expression). It’s easier to add fields inside a structure than to define parallel parameters each time.

Scope of the expression

We intend to keep this scope narrow:

  • Jira Expressions only. No other languages or dialects.

  • Transition-time data only. The expression can access the work item, project, transition, and user. It cannot access data unavailable at transition time.

  • Evaluated inline, on Jira’s side, before the post function executes — not after the transition completes or before it starts.

  • A simple editing experience. A basic builder for common conditions, AI assistance to draft expressions, and direct expression entry for advanced cases.

Relationship to Marketplace apps

Many apps provide a form of conditional gating for post functions today. These typically run as part of hooks that fire after the transition. Apps offer richer authoring experiences, support alternative languages and allow deeper integrations with data or systems that Jira does not have access to during a transition.

As such, our main concern is confusion rather than competition. With both a native conditional gate and an app conditional gate, a post function may have two different reasons for not executing with configuration over two different surfaces once we enable this for Forge or Connect apps. Differences between the native configuration and the app’s configuration can may also create some degree of confusion or lead customers to wonder which one to use and when.

We do think it’s worth considering how they both can work together, particularly where a decision can be made during a transition and potentially cut out unnecessary invocations where an app may have nothing to do if it was triggered. This aligns with RFC-143: Reduce Forge invocations from bulk operations. We want to work with app authors to get the details right and ensure native gating is useful alongside app capabilities.

Asks

We welcome any reactions to this RFC. We’re especially interested in:

  1. What conditional gating do your apps provide for workflow post functions today, and how would a native condition could sit alongside it? Would it be complementary, redundant, or confusing?

  2. Where do users get confused when configuring conditional post functions, in Jira and in apps? What have you learned from supporting them?

  3. What tools would help users manage, validate, test, or troubleshoot these expressions? Would an extension point around expression authoring or validation help?

  4. Would you want a native conditionExpression to gate your app’s post function so Jira skips the invocation entirely?

  5. Is treating a failed or erroring condition as “do not run” the right default? Would you want an opt-in “run anyway” behavior of , and when?

  6. Is transition-time data (work item, project, transition, user) sufficient for the gating customers ask for? If not, what else would they need to reference?

  7. Does the JSON-encoded conditionExpression shape cause problems when reading or writing workflows via the REST API?

Thanks for sharing this RFC. We’re interested in having ScriptRunner included in the Beta / EAP so we can test how it interacts with our functionality. Is there an existing participant list that we can be added to, and what is the timeline and access process for late October / early November 2026?

Thank you in advance

Hi @VelizarAngelov
Thanks for your interest. I’m a Product Manager on Jira Cloud working on this feature. This feature is likely to be available as an Opt-in Beta via Jira labs around mid December. That should give you the ability to turn the feature on for any Jira site you have and test the same.

Just to highlight, as mentioned above, these conditions will live natively in Jira and will be available for 1P rules only as of now. So you will be able to test them on the same. Once released, we would love to get feedback from you on how we could potentially extend (or not) these to 3P rules like ScriptRunner. I will update this thread with a feedback link once the Beta is live.

We have a Jira app with several admin post functions that deal with signatures. An expression to skip processing entirely would be more efficient then currently where we get all work items in a project, even ones with no signature metadata.

Responses

  1. No specific custom conditional gating in our post functions (like issue types or issue status). Our PF config is action based, not filtering. The PF examines the target issue and will skip processing if the current state doesn’t apply. (e.g. post function to reset signatures will noop if there are no signatures to clear)

  2. Don’t see config confusion if the expression is clearly a filter before the PF action is dispatched.

  3. Expression validator to test via curl would be useful.

  4. Yes, conditionExpression should skip invocation.

  5. ConditionExpression failure should not silently skip processing. (or at least be configurable). Otherwise very difficult as a vendor to support if we don’t get any logs at all for a post function. Maybe diagnostic mode switch to surface expression errors, or even call the post function with the expression error so vendor can log it.

  6. Transition-TIME data is sufficient if the expression can access work item properties. e.g. issue.properties[“propname”].appFlag === true

  7. N/A for us.

Thanks for the feedback @Chris_at_DigitalRose . I was about to close the discussion, so I’ll hold it open for a few more days.

Skipping processing

You’re right. An expression that skips upfront processing would be more efficient, especially for apps that want to avoid being invoked unnecessarily. We’ve received mixed feedback on whether apps would adopt this for efficiency alone though, since many already use conditional logic for the same purpose.

We’re also undecided whether this should apply to every post-function, whether the conditional expression for app rules should be admin-controlled, app-controlled for app rules, or some combination. We planned to do the initial launch without app support, then consider how much interest there is in this feature from apps before building out broader app features or extension points. Hence this RFC.

Testing expressions via curl
We have the analyse Jira expressions API. Would that be enough for testing, or do you we something more?

Expression failures should not silently skip processing

We’re discussing this in team. We believe a runtime error in an expression should not fail and block the whole transition; it should skip the function. We welcome feedback.

One idea from @edalgliesh, if admins don’t want to skip failures, we could add a pragma or operator in the expression so authors can specify whether runtime failures should error or be skipped, or even enable debugging.

For example, add a control statement in the language to indicate failure handling.

(issue.assignee == 1234-543676-43576) |~ throw

onError:FAIL (issue.assignee == 1234-543676-43576)

onError:true (issue.assignee == 1234-543676-43576)

debug:true (issue.assignee == 1234-543676-43576)

But that would require some more discussion.

Feedback on runtime failures

We agree some form of failure feedback is needed, though it may not be in the initial release. Options include tracking recent errors per rule and showing them somewhere, or a debug mode that adds a comment with details.

Transition-time data
You should have access to everything at transition time. I believe properties can be accessed at transition time.

Some question for you

How would you configure the conditions for your apps rules?

  • Would you need new extension or configuration points in the app definition or Forge, or would you set them through the workflow APIs?
  • Would you expect admins to be able to edit or tweak the configuration with other conditions?

Would you need new extension or configuration points in the app definition or Forge, or would you set them through the workflow APIs?

I think ideal would be to have a jiraExpression in the post function module in the manifest, for example, we use simple jiraExpressions like the following in jira:issueActivity and issuePanel displayConditions. Something like the following would be clean and effective.

  jira:issueActivity
    - key: page-issue-audit-tab
      ...
      displayConditions: 
        jiraExpression: >-
          issue.properties['esign-audit.digitalrose.dev'] != null

Would you expect admins to be able to edit or tweak the configuration with other conditions?

Optional. A workflow action filter could maybe added to the workflow editor, but to an earlier point in this RFC that might add too much confusion/complexity.

  • Today most of our customers would set up a different workflow by project/issue type if they wanted different post functions to be in scope. And practically customers are less concerned about efficiency and would only use the workflow action filter if they wanted to limit functions for specific business rules.
  • If customer tweaks are within the marketplace app, then it is part of the pf config which is sent into the app when the pf is dispatched so that doesn’t reduce invocations.

Thanks for the input, that’s a useful distinction.

Most of this RFC is about user-facing configuration for admins in the workflow editor, along with exposing the expression in the API and the behaviour at runtime.

As you say, many users end up building separate workflows to get around this today, and the idea is that they shouldn’t have to for simple cases. For example, maybe I want the transition to set different labels during a transition based on some condition, or as in our original driver for this work, not triggering an agent when a work item unless some condition passes.

It sounds like use case on your end would be more about leveraging an extension point in the module definition, so your app can supply its own condition that decides whether the function runs. Is that right, or would you also want admins to be able to adjust it?

As for pfConfig, there’s no reason we couldn’t have Jira evaluate part of that config if there’s a clear need and a solid schema shape for it and not trigger the invocation? Or we could place the config outside of the pfConfig and allow admins to control that externally to the app if they wish?

For a customer focused solution I can see the benefit of a conditionalExpression as part of the Jira workflow to selectively enable a configured workflow action. I see this as helping customers cherry pick at a micro level which business cases they want the action(s) to fire on. It appears similar to a branch in the automation rules engine.

As mentioned a conditionalExpression in the manifest would be an efficiency improvement for Jira and the vendors for a macro level for where the action just doesn’t apply to that issue.

I would hesitate to put the workflow conditional expression complexity into the pfConfig itself as then Jira would be dependent on having each vendor opting in to implement, store and validate those expressions in their own proprietary UI. The workflow resident condition could be universal and apply to all actions, but jira native and third party.

True, though some do have their own variation of that today.

I guess what this is leading to is that an app controlled condition is a different beast to an admin configured condition so they would ideally be seperate if we took that path.

Hey everyone,

I’m going to close of this RFC now.

An open beta of the admin managed conditions should be out by mid December.

@Chris_at_DigitalRose I’ve raised https://jira.atlassian.com/browse/ECO-1852 to capture the suggestion you raised for an app controlled version of this as well. I think it’s a good idea, and I’ve pinged it to a few teams in this forge/workflows area for input.

and also… before I forget. Thank you all for your input on this.