JIRA JQL Translation Skill
When users search JIRA with natural language queries, use this skill to generate appropriate JQL (JIRA Query Language) queries that are syntactically correct, semantically meaningful, and performant.
Core Translation Principles
- •Understand Intent: Interpret what the user wants to find
- •Apply Smart Defaults: Use fuzzy matching and expansions for common patterns
- •Prioritize Performance: Always include project filters when possible
- •Be Transparent: Generate clear, readable JQL that users can learn from
- •Add Context: Include sensible ORDER BY clauses for immediate usefulness
Translation Patterns
Fuzzy Status Matching
Users rarely know exact status names. Apply intelligent fuzzy matching:
"open" / "opened" / "active" / "not done":
status IN (Open, 'To Do', 'In Progress', 'Refinement In Progress', New, Blocked)
"closed" / "done" / "finished" / "completed":
status IN (Closed, Done, Resolved, 'Refinement Complete')
"in progress" / "working on" / "active development":
status IN ('In Progress', 'Code Review', Testing, 'Refinement In Progress')
"blocked" / "stuck" / "waiting":
status IN (Blocked, Waiting, 'Pending Review', 'Pending Approval')
"needs review" / "ready for review":
status IN ('Code Review', 'Pending Review', 'Ready for QA')
Release/Version Queries
Teams use both fixVersion field AND labels inconsistently. Always check both automatically:
"release-3.2" / "version 3.2" / "3.2 release":
(fixVersion = 'release-3.2' OR labels = 'release-3.2')
"targeted to X" / "planned for X":
(fixVersion = 'X' OR labels = 'X')
Pattern: Always use OR to check both fixVersion and labels for any version/release query.
Link Following
"linked to RHAISTRAT-123" / "related to RHAI-456":
issue IN linkedIssues(RHAISTRAT-123)
"blocks RHAIENG-789" / "blocking KEY":
issue IN linkedIssues(RHAIENG-789, "blocks")
"blocked by KEY":
issue IN linkedIssues(KEY, "is blocked by")
"depends on KEY":
issue IN linkedIssues(KEY, "depends on")
Common link types: Relates, Blocks, Clones, Duplicates, Causes, Depends on
Ownership Queries
"my issues" / "assigned to me" / "mine":
assignee = currentUser()
"created by me" / "I created" / "I reported":
reporter = currentUser()
"unassigned" / "no assignee" / "needs owner":
assignee IS EMPTY
"assigned to john" / "john's issues":
assignee = john
Note: Usernames in JIRA are typically lowercase, without spaces.
Priority Queries
"high priority" / "urgent" / "critical":
priority IN (Highest, High, Critical)
"low priority":
priority IN (Lowest, Low)
"medium priority" / "normal":
priority = Medium
Issue Type Queries
"bugs" / "defects":
issuetype = Bug
"features" / "stories" / "user stories":
issuetype IN (Feature, Story, 'User Story')
"tasks" / "chores":
issuetype = Task
"epics":
issuetype = Epic
"subtasks" / "sub-tasks":
issuetype IN subTaskIssueTypes()
Date/Time Queries
"last week" / "past week" / "this week":
updated >= -7d
"yesterday" / "last 24 hours":
updated >= -1d
"last month":
updated >= -30d
"today" / "updated today":
updated >= startOfDay()
"created this month":
created >= startOfMonth()
"overdue":
due < now() AND resolution = Unresolved
Sprint Queries
"current sprint" / "active sprint":
sprint IN openSprints()
"no sprint" / "backlog" / "not in any sprint":
sprint IS EMPTY
"sprint 25" / "sprint X":
sprint = X
Team/Group Queries
"assigned to the QA team" / "QA's issues":
assignee IN membersOf("qa") OR assignee IN membersOf("quality-assurance")
"created by the dev team":
reporter IN membersOf("developers")
Label Queries
"labeled X" / "tagged X" / "with label X":
labels = X
"requires architecture review":
labels = requires_architecture_review
Note: Labels are typically lowercase with underscores or hyphens.
Resolution Queries
"unresolved" / "not done" / "still open":
resolution = Unresolved
"resolved" / "fixed":
resolution IS NOT EMPTY
JQL Syntax Reference
Operators
| Operator | Usage | Example |
|---|---|---|
= | Equals (exact match) | status = Open |
!= | Not equals | priority != Low |
> | Greater than | votes > 10 |
>= | Greater or equal | created >= -7d |
< | Less than | votes < 5 |
<= | Less or equal | duedate <= now() |
IN | Matches any value in list | status IN (Open, 'In Progress') |
NOT IN | Excludes all values in list | status NOT IN (Closed, Done) |
~ | Contains (text search) | summary ~ "authentication" |
!~ | Does not contain | summary !~ "deprecated" |
IS EMPTY | Field has no value | assignee IS EMPTY |
IS NOT EMPTY | Field has a value | labels IS NOT EMPTY |
IS NULL | Same as IS EMPTY | fixVersion IS NULL |
IS NOT NULL | Same as IS NOT EMPTY | component IS NOT NULL |
WAS | Had value in the past | status WAS 'In Progress' |
WAS IN | Was any of values | status WAS IN (Open, New) |
WAS NOT | Was not value | assignee WAS NOT john |
CHANGED | Field value changed | priority CHANGED |
Functions
| Function | Description | Example |
|---|---|---|
currentUser() | Currently logged-in user | assignee = currentUser() |
linkedIssues(key) | All issues linked to key | issue IN linkedIssues(RHAI-123) |
linkedIssues(key, linkType) | Issues with specific link type | issue IN linkedIssues(RHAI-123, "blocks") |
membersOf(group) | Users in a group | assignee IN membersOf("developers") |
now() | Current date/time | created > now(-1h) |
startOfDay([offset]) | Start of today (or offset) | created >= startOfDay() |
endOfDay([offset]) | End of today (or offset) | due <= endOfDay() |
startOfWeek([offset]) | Start of week | created >= startOfWeek() |
endOfWeek([offset]) | End of week | due <= endOfWeek() |
startOfMonth([offset]) | Start of month | created >= startOfMonth() |
endOfMonth([offset]) | End of month | due <= endOfMonth() |
startOfYear([offset]) | Start of year | created >= startOfYear() |
endOfYear([offset]) | End of year | resolved <= endOfYear() |
openSprints() | All active sprints | sprint IN openSprints() |
closedSprints() | All completed sprints | sprint IN closedSprints() |
futureSprints() | All future sprints | sprint IN futureSprints() |
subTaskIssueTypes() | All subtask types | issuetype IN subTaskIssueTypes() |
issueHistory() | Search issue history | Advanced usage |
Time offset examples:
- •
now(-1h)- 1 hour ago - •
startOfDay(-7)- Start of day 7 days ago - •
startOfMonth(1)- Start of next month
Fields
| Field | Description | Example Values |
|---|---|---|
project | Project key | RHAISTRAT, RHAIENG, RHAIRFE |
summary | Issue title | "Add authentication support" |
description | Issue description | Free text |
issuetype | Type of issue | Bug, Feature, Story, Task, Epic |
status | Current status | Open, 'In Progress', Done, Closed |
priority | Priority level | Highest, High, Medium, Low, Lowest |
assignee | Assigned user | jdoe, currentUser() |
reporter | Created by | jsmith, currentUser() |
created | Creation date | "2025-01-15", -7d |
updated | Last updated | -1d, startOfDay() |
resolved | Resolution date | -30d, now() |
due | Due date | "2025-02-01", endOfWeek() |
labels | Tags/labels | documentation, security |
component | Component | Authentication, UXD, API |
fixVersion | Target version | 1.5.0, release-3.2 |
affectsVersion | Found in version | 1.4.0 |
resolution | Resolution status | Unresolved, Fixed, Won't Fix |
sprint | Sprint | Sprint 25, openSprints() |
comment | Issue comments | Free text search |
votes | Number of votes | 10, >5 |
watchers | Number of watchers | 3, >=1 |
text | All text fields | Searches summary, description, comments |
Logical Operators
| Operator | Usage | Example |
|---|---|---|
AND | All conditions must be true | project = RHAI AND status = Open |
OR | Any condition must be true | priority = High OR priority = Highest |
NOT | Negates a condition | NOT status = Closed |
Parentheses for grouping:
(priority = High OR priority = Highest) AND status = Open
Ordering
ORDER BY sorts results:
ORDER BY priority DESC ORDER BY created ASC ORDER BY priority DESC, updated DESC
Directions: ASC (ascending), DESC (descending)
Quoting Rules
Quote multi-word values with single or double quotes:
status = 'In Progress' status = "Code Review" project IN (RHAI, RHAIENG) # Single-word values don't need quotes
Quote special characters:
summary ~ "user's authentication"
Date Formats
Relative dates:
- •
-1d- 1 day ago - •
-2w- 2 weeks ago - •
-3M- 3 months ago - •
-1y- 1 year ago - •
-30m- 30 minutes ago - •
-2h- 2 hours ago
Absolute dates:
- •
"2025-01-15" - •
"2025/01/15" - •
"15/Jan/25"
Functions:
- •
now() - •
startOfDay(),endOfDay() - •
startOfWeek(),endOfWeek()
Complex Translation Examples
Example 1: "my open bugs in RHAIENG"
User Intent: Find bugs assigned to me that aren't finished yet, in a specific project
Generated JQL:
project = RHAIENG AND issuetype = Bug AND assignee = currentUser() AND status IN (Open, 'To Do', 'In Progress', New, Blocked) ORDER BY priority DESC, updated DESC
Why:
- •Project filter first (performance)
- •Fuzzy status matching ("open" → multiple statuses)
- •Sensible ordering (high priority first, then recently updated)
Example 2: "features targeted to release-3.2 that are still open"
User Intent: Find features planned for a release that aren't done yet
Generated JQL:
issuetype IN (Feature, Story, 'User Story') AND (fixVersion = 'release-3.2' OR labels = 'release-3.2') AND status NOT IN (Done, Closed, Resolved, 'Refinement Complete') ORDER BY priority DESC
Why:
- •Checks both fixVersion and labels (teams use inconsistently)
- •Excludes "closed" statuses (fuzzy matching)
- •Orders by priority for focus
Example 3: "issues linked to RHAISTRAT-123"
User Intent: Find all issues with any link to a specific issue
Generated JQL:
issue IN linkedIssues(RHAISTRAT-123) ORDER BY type ASC, key ASC
Why:
- •Uses linkedIssues() function
- •Orders by type for grouping (bugs, features, etc.)
Example 4: "my issues updated in the last week"
User Intent: Find my issues with recent activity
Generated JQL:
assignee = currentUser() AND updated >= -7d ORDER BY updated DESC
Why:
- •Simple and direct
- •Orders by most recent first
Example 5: "unassigned high priority bugs in RHAIENG"
User Intent: Find urgent bugs that need an owner
Generated JQL:
project = RHAIENG AND issuetype = Bug AND priority IN (Highest, High, Critical) AND assignee IS EMPTY ORDER BY priority DESC, created DESC
Why:
- •Project filter first
- •Fuzzy priority matching ("high priority" → multiple levels)
- •Orders by priority then age
Example 6: "bugs created by me that block other issues"
User Intent: Find bugs I reported that are blockers
Generated JQL:
issuetype = Bug AND reporter = currentUser() AND issue IN linkedIssues(*, "blocks") ORDER BY created DESC
Note: The * wildcard with linkedIssues may not work in all JIRA versions. Alternative approach:
issuetype = Bug AND reporter = currentUser() ORDER BY created DESC
Then filter manually for blockers.
Example 7: "features in the current sprint assigned to the QA team"
User Intent: Find features in active sprint assigned to QA
Generated JQL:
issuetype IN (Feature, Story)
AND sprint IN openSprints()
AND (assignee IN membersOf("qa") OR assignee IN membersOf("quality-assurance"))
ORDER BY rank ASC
Why:
- •Uses openSprints() for current sprint
- •Checks multiple possible group names
- •Orders by rank (sprint order)
Example 8: "my overdue tasks"
User Intent: Find tasks assigned to me that are past due date
Generated JQL:
assignee = currentUser() AND due < now() AND resolution = Unresolved ORDER BY due ASC
Why:
- •Checks due date is in the past
- •Excludes resolved issues
- •Orders by most overdue first
Example 9: "issues created this month in RHAISTRAT project with no labels"
User Intent: Find recent issues that haven't been tagged yet
Generated JQL:
project = RHAISTRAT AND created >= startOfMonth() AND labels IS EMPTY ORDER BY created DESC
Why:
- •Uses startOfMonth() for "this month"
- •IS EMPTY for "no labels"
- •Recent first ordering
Example 10: "bugs in release-2.5 that were closed but are now reopened"
User Intent: Find regressions in a specific release
Generated JQL:
issuetype = Bug AND (fixVersion = 'release-2.5' OR labels = 'release-2.5') AND status WAS Closed AND status = Open ORDER BY updated DESC
Why:
- •Uses WAS operator for history
- •Checks both version field and labels
- •Current status is Open (reopened)
Translation Guidelines
1. Always Include Project Filters When Possible
Bad (slow, searches all issues):
assignee = currentUser() AND status = Open
Good (fast, limits scope):
project = RHAIENG AND assignee = currentUser() AND status = Open
Performance: 10-100x faster with project filter.
2. Use Fuzzy Matching for Status and Priority
Don't require users to know exact status names. Map common terms to multiple statuses:
- •"open" → Open, To Do, In Progress, New
- •"high priority" → Highest, High, Critical
3. Always Expand Release Queries
Check both fixVersion AND labels automatically:
(fixVersion = 'X' OR labels = 'X')
4. Add Sensible ORDER BY Clauses
Don't return unordered results. Choose ordering based on intent:
- •Priority:
ORDER BY priority DESC - •Recency:
ORDER BY updated DESCorORDER BY created DESC - •Due date:
ORDER BY due ASC - •Sprint:
ORDER BY rank ASC
5. Quote Multi-Word Values
status = 'In Progress' # Correct status = In Progress # Wrong (syntax error)
6. Prefer Positive Conditions
Less clear:
NOT status = Closed
More clear:
status IN (Open, 'In Progress', 'To Do')
7. Use Functions for Dynamic Values
Static (becomes outdated):
assignee = jdoe
Dynamic (works for any user):
assignee = currentUser()
8. Combine Related Conditions
Verbose:
status = Open OR status = 'In Progress' OR status = 'To Do'
Concise:
status IN (Open, 'In Progress', 'To Do')
9. Be Explicit About Intent
If user says "my bugs", include:
- •issuetype = Bug
- •assignee = currentUser()
- •Likely want: status IN (open statuses)
- •Good ordering: priority DESC
10. Handle Ambiguity with Sensible Defaults
If query is vague like "issues", default to:
assignee = currentUser() AND resolution = Unresolved ORDER BY updated DESC
Assume user wants their own open issues.
Common Patterns Quick Reference
| User Says | Generate JQL |
|---|---|
| "my issues" | assignee = currentUser() AND resolution = Unresolved |
| "my bugs" | issuetype = Bug AND assignee = currentUser() AND status IN (...) |
| "my open bugs" | Above + fuzzy status |
| "bugs in PROJECT" | project = PROJECT AND issuetype = Bug |
| "high priority" | priority IN (Highest, High, Critical) |
| "release-X" | (fixVersion = 'release-X' OR labels = 'release-X') |
| "last week" | updated >= -7d |
| "today" | updated >= startOfDay() |
| "unassigned" | assignee IS EMPTY |
| "created by me" | reporter = currentUser() |
| "overdue" | due < now() AND resolution = Unresolved |
| "current sprint" | sprint IN openSprints() |
| "linked to KEY" | issue IN linkedIssues(KEY) |
| "no labels" | labels IS EMPTY |
Performance Optimization Tips
1. Project Filter First
Always include project in queries when possible.
2. Avoid Text Searches When Possible
Slow:
summary ~ "authentication" OR description ~ "authentication"
Faster:
text ~ "authentication" # Searches summary, description, comments
Even better (if possible):
labels = authentication # Field match is fastest
3. Limit OR Conditions
Slower:
project = A OR project = B OR project = C OR ... # Many ORs
Faster:
project IN (A, B, C, ...) # Single IN clause
4. Use Indexed Fields
Prefer these (indexed in most JIRA instances):
- •project
- •status
- •priority
- •assignee
- •reporter
- •issuetype
Avoid heavy reliance on:
- •text searches (
~operator) - •comments
- •description
Error Prevention
Common Mistakes to Avoid
1. Missing Quotes:
status = In Progress # WRONG (syntax error) status = 'In Progress' # CORRECT
2. Wrong Operator for Field Type:
created ~ "2025-01-15" # WRONG (~ is for text) created = "2025-01-15" # CORRECT (= for dates)
3. Using != with Text Fields:
summary != "test" # NOT SUPPORTED NOT summary ~ "test" # Use this instead
4. Case Sensitivity:
- •Field names: Case-insensitive (
status=Status=STATUS) - •Values: Case-sensitive (
status = Open≠status = open) - •Functions: Case-insensitive
5. Reserved Words: Don't use these as unquoted values: AND, OR, NOT, EMPTY, NULL, ORDER, BY
Web References
For the most up-to-date JQL documentation:
- •Advanced Search Guide: https://support.atlassian.com/jira-software-cloud/docs/use-advanced-search-with-jira-query-language-jql/
- •JQL Fields Reference: https://support.atlassian.com/jira-software-cloud/docs/jql-fields/
- •JQL Operators: https://support.atlassian.com/jira-software-cloud/docs/jql-operators/
- •JQL Functions: https://support.atlassian.com/jira-software-cloud/docs/jql-functions/
- •JQL Cheat Sheet: https://www.atlassian.com/software/jira/guides/jql/cheat-sheet
- •linkedIssues Function: Check Atlassian documentation for link type names in your JIRA instance
Usage in /jira:search Command
When the /jira:search command invokes this skill, you should:
- •Parse the user's natural language query
- •Identify key components (project, issue type, status, owner, etc.)
- •Apply fuzzy matching and smart expansions
- •Construct syntactically correct JQL
- •Add sensible ORDER BY clause
- •Return the JQL string only (no explanation in the JQL itself)
The command will show the JQL to the user with an explanation before execution.
Example workflow:
User query: "my open bugs in RHAIENG"
Your thought process:
- •"my" → assignee = currentUser()
- •"bugs" → issuetype = Bug
- •"in RHAIENG" → project = RHAIENG
- •"open" → status IN (Open, 'To Do', 'In Progress', New, Blocked)
- •Add ordering → ORDER BY priority DESC, updated DESC
Generated JQL:
project = RHAIENG AND issuetype = Bug AND assignee = currentUser() AND status IN (Open, 'To Do', 'In Progress', New, Blocked) ORDER BY priority DESC, updated DESC
Remember: Your goal is to translate user intent into powerful, correct, performant JQL. Be smart, be helpful, and always think about what the user really wants to find.