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
This RFC proposes a new RichDocument type for Jira expressions. It helps users work with rich text fields like Description, Environment, paragraph custom fields, and comment bodies regardless of their format. It can be built on over time, adding utility functions that make these fields easier to work with in Jira expressions.
- Publish: October 1, 2026
- Discuss: October 5, 2026–October 19, 2026
- Resolve: October 26, 2026
Problem
The suggestion JRACLOUD-93971 called for some kind of consistent handling of rich text fields in Jira expressions. This RFC proposes a way to provide it.
The challenge we have is that a rich text field can reach a Jira expression in several forms, depending on the experience or API that makes the request:
- a wiki markup
String(older create and transition screens, REST API v2), - an ADF document
Map(the new create and transition experiences, REST API v3), - a
RichTextobject (system fields such asissue.description), or null, blank text, or an empty document if the field has never been filled in.
This is mostly a historical artefact that goes back to how ADF was introduced into the product. Changing the current behaviour is also very hard, as changes to existing types can break scripts that have already adapted to the behaviour. As such, the current guidance for customers has been to work around this by trying to use the RichText type.
let plainTextValue = value => typeof value == 'Map' ? new RichText(value).plainText : typeof value == 'RichText' ? value.plainText : value;
While this approach has worked, it isn’t straightforward:
- Script authors must handle variations in shape, which makes working with these types difficult.
- It implies to users that
plainTextis unformatted text, when it is often wiki text. - It doesn’t make working with the content any easier, making users do a lot of
trim()andreplace()calls to figure out whether the text is blank. new RichText(map)can’t always construct the object successfully, and fails with an evaluation error on documents it can’t convert.
Proposed Solution
We propose a RichDocument type, created with RichDocument.of(value). It retains the value in its original format, validates it once, and converts it only when an expression requests another format.
We’re adding a new type rather than extending RichText for two reasons. Most rich text values never arrive as a RichText, and creating one from a document is a pain point today. A separate type lets us accept every format safely as an additive change without affecting existing expressions.
Initially, we’re going to keep this very simple and provide just a few utilities, as listed below.
| Member | Returns | Behaviour |
|---|---|---|
RichDocument.of(value) |
RichDocument |
Accepts an ADF document, a wiki String, a RichText object, or null. Treats null as an empty document. Produces an evaluation error for an invalid ADF document or a value that is not rich text. Does not convert the value. |
isBlank() |
Boolean |
Whether the document is empty or contains only whitespace and line breaks. Use this for required-field validators: it gives the same answer in every format. |
asWikiText() |
String |
Returns wiki markup, converting only if the document is in ADF format. |
asAdfMap() |
Map |
Returns an ADF document, converting only if the document is in wiki markup format. |
We imagine these being used like this:
let descriptionDoc = RichDocument.of(issue.description)
// Is the description filled in?
!descriptionDoc.isBlank()
// Give me a wiki version of the description
descriptionDoc.asWikiText()
// Has anyone left a non-blank comment?
issue.comments.some(c => !RichDocument.of(c.body).isBlank())
// Return 'Please describe the change.' when the field is blank, otherwise return true
RichDocument.of(issue.customfield_10797).isBlank() ? 'Please describe the change.' : true
What counts as blank?
Blank means the content is empty, null or contains only whitespace.
In an ADF document this gets muddied a bit. Blank means every top-level block is a paragraph containing only whitespace text and hard breaks. Any other node (a mention, emoji, media, table, heading or rule) counts as content, even if that node is itself empty.
What if the document is malformed?
RichDocument.of will reject invalid documents and values that aren’t rich text at runtime, and the error will be reported as an expression evaluation failure. Users can still choose to handle this if they wish, as shown below:
try { !RichDocument.of(issue.customfield_10797).isBlank() } catch { 'The field could not be read.' }
Can a RichDocument be returned?
RichDocument is intended to act as a helper for use within an expression, not a value to return. If an expression returns one, the evaluate API returns the string "RichDocument", just as it returns a signature for a function.
What happens with the RichText type?
On our end, we want to avoid breaking existing scripts. That’s why we’re going with a new type rather than adjusting the old one. As such, RichText, new RichText(map), and plainText remain unchanged; there is no plan to remove them for the time being. The workaround above will continue to work wherever it works today.
Asks
We would like feedback from app developers and admins who write Jira expressions for rich text fields. In particular:
- Would the definition of blank match what your validators and conditions mean by “filled in”? Would you count any node types differently?
- Are there functions or features that would be useful to add to
RichDocument, and how would you imagine they would work? - Are the names
RichDocument,of,isBlank,asWikiText, andasAdfMapclear?
References
- JRACLOUD-93971 — Consistent handling of rich text fields in Jira expressions
- JRACLOUD-99526 — Validator fails to recognise a cleared paragraph field on the new transition experience
- JRACLOUD-93701 — 3rd party app validators and conditions for rich text custom fields
- Changes affecting workflow validators on the new Global Issue Create modal
- Changes affecting workflow validators and post functions on the new issue transition experience
- Future proofing Jira Expressions following the release of the new workflow transition experience
- Jira expressions: Working with JSON
- Jira expressions type reference: RichText