Creating a Character Limit Validator in Jira Cloud with JMWE
Purpose: Create a workflow Validator in Jira Cloud (using Jira Misc Workflow Extensions - JMWE) that blocks a transition when a Paragraph/Multi-line Text field exceeds a maximum number of characters.
Overview
In Jira Cloud, rich-text (paragraph) fields are stored as a nested content structure rather than a plain string. That’s why a simple length comparison fails. This guide shows how to build a Jira Expression-based Validator in JMWE that traverses the paragraph structure, sums all text node lengths, and enforces a character limit.
Applies to: Jira Cloud + JMWE. You’ll need Workflow edit permissions and the custom field’s ID (e.g., customfield_12345).
Prerequisites
JMWE app installed on Jira Cloud
A Paragraph or Multi-line Text custom field already created
Workflow transition where you want to enforce the limit
Step-by-step: Add the Validator
Open the target workflow in Jira Cloud (Project settings > Workflows), switch to the Diagram view, and select the transition to validate.
Add a Validator: choose Build-your-own (scripted) Validator and set the Validator type to Jira Expression. For more details, see https://appfire.atlassian.net/wiki/spaces/MWECS/pages/449315100.
Paste the expression below, replacing customfield_XXXXX with your field ID, and 110 with your desired max length.
Configure the error message (shown to users when the limit is exceeded).
Publish the workflow and test the transition.
Jira Expression (Validator)
issue.customfield_XXXXX != null &&
(
issue.customfield_XXXXX.content
.flatMap(p => p.content)
.filter(n => n.text != null)
.map(n => n.text.length)
.reduce((sum, len) => sum + len, 0)
) <= 110Tip: Document the character limit you've chosen (e.g., 110) in your workflow description or internal runbook so other admins can easily find and update it later. If different fields need different limits, create a separate validator for each with its own threshold.
How the expression works
Null check: Ensures the field is not null before counting. If the field is null (unset), the entire expression evaluates to false and the transition is blocked. If the field should be optional (i.e., allow null), change the expression to:
issue.customfield_XXXXX == null || ( ... sum ... ) <= 110.content.flatMap(...): Flattens paragraph blocks into a single array of inline nodes.
filter(n => n.text != null): Keeps only nodes with text (skips hard breaks and formatting-only nodes).
map(...length): Converts each text node to its character length.
reduce(...): Sums all lengths and compares against the maximum allowed.
Optional variants (copy/paste)
Customizing the solution
Different field: Replace customfield_XXXXX with your actual field ID. You can find it by viewing the field’s context URL or using the Admin helper tools.
Different max length: Change 110 to any integer limit that fits your policy.
Whitespace policy: If you want to trim leading/trailing whitespace before counting, convert
n.text.lengthton.text.trim().length.
Common pitfalls and troubleshooting
Plain length checks fail: Paragraph fields are rich-text objects, not strings. Always traverse the content array as shown.
Hard breaks count: Line breaks are represented as nodes (e.g.,
hardBreak) without text. The filter step excludes them from counting.Empty field handling: If the field object exists but has no text content, the sum equals 0 and the transition is allowed. However, if the field is completely null/unset, the null check on line 1 blocks the transition. If the field must be non-empty AND under the limit, replace the null check with:
issue.customfield_XXXXX != null && ( ... sum ... ) > 0 && ( ... sum ... ) <= 110.
Worked example
Suppose your field is customfield_10181 and your limit is 110 characters. Use this expression:
issue.customfield_10181 != null &&
(
issue.customfield_10181.content
.flatMap(p => p.content)
.filter(n => n.text != null)
.map(n => n.text.length)
.reduce((sum, len) => sum + len, 0)
) <= 110Error message suggestion
“Your response exceeds the maximum allowed length of 110 characters for this field. Please shorten your text.”