JQL Function Pack for Jira: documentation
JQL Function Pack adds six JQL functions to Jira Cloud, for sprint scope changes, sprint dates, and filtering issues by their parent's or children's fields.
On this page: Overview · Functions · How current a result is · Limits · Known limitations · Questions
Help: support@accounts.datadelight.co. Policies: privacy policy, terms of service.
Overview
JQL Function Pack adds six JQL functions to Jira Cloud: two for sprint scope changes, two for sprint dates, and two that filter issues by their parent's or their children's fields. They work wherever JQL does: the issue search bar, saved filters, board filters and dashboard gadgets. The app keeps no index or database of its own; every answer is read from Jira when it is computed, and the app runs on Atlassian's own infrastructure (Runs on Atlassian).
Use each function as issue in fn(...) or issue not in fn(...), with the arguments in double quotes.
Functions
addedToSprintAfterStart(sprint)
Issues that joined the sprint after it started: scope added. sprint is the sprint's name or its id.
- Examples:
issue in addedToSprintAfterStart("Team Rocket Sprint 14"),issue in addedToSprintAfterStart(231) AND status != Done. - Counts an issue moved in from the backlog or from another sprint, and an issue created straight into the sprint, after the start time.
- Counts it even if it left again later, and counts an issue that was removed and then added back.
- Does not count anything added before the start (planning) or after the sprint was completed.
- A sprint that has not started matches no issues.
removedFromSprint(sprint)
Issues that left the sprint while it ran: removed to the backlog or moved to another sprint between its start and its completion.
- Examples:
issue in removedFromSprint("Team Rocket Sprint 14"),issue in removedFromSprint(231) AND sprint in openSprints(). - Counts an issue moved to another sprint, and an issue removed and later added back (it did leave).
- Does not count removals before the start (planning). When a sprint is completed, Jira moves unfinished issues to the next sprint but keeps the completed sprint in their Sprint field, so that is not a removal.
inSprintsStartingBetween(from, to)
Issues in any sprint whose start date falls between from and to, inclusive. Dates are YYYY-MM-DD (the whole day, in UTC) or a full ISO date-time such as 2026-10-23T20:00:00Z.
- Examples:
issue in inSprintsStartingBetween("2026-10-01", "2026-12-31"),issue in inSprintsStartingBetween("2026-10-01", "2026-10-31") AND project = ABC. - Either end may be left empty for an open range, but on a site with years of sprints give both ends (see Limits).
inSprintsEndingBetween(from, to)
The same for the sprint's end date (the planned end date set when the sprint was started).
- Examples:
issue in inSprintsEndingBetween("2026-10-01", "2026-10-31"),issue in inSprintsEndingBetween("2026-04-01", "2026-06-30") AND resolution is EMPTY. - An open start counts every earlier sprint. On a test site with about 2,700 sprints, an open-ended range matched more than 1,000 sprints and was refused, while one quarter matched about 180 to 200.
subtasksWhere(parentJql)
Subtasks whose parent matches the JQL in quotes, including the parent's custom fields. Works in company-managed and team-managed projects, and for parents in another project than the subtask.
- Examples:
issue in subtasksWhere("project = ABC AND \"Customer tier[Dropdown]\" = Gold"),issue in subtasksWhere("priority = Highest") AND assignee = currentUser(). - When more than 1,000 issues match the quoted JQL, it lists only those that have subtasks, so a broad query over issues without subtasks is not refused for Jira's 1,000-value limit.
parentsWhere(childJql)
Parents with at least one child matching the JQL in quotes: a story whose subtask matches, an epic whose story matches, at every level of a hierarchy. It returns the direct parent; an epic two levels up from a matching subtask is not included.
- Examples:
issue in parentsWhere("issuetype = Sub-task AND status = Blocked"),issue in parentsWhere("issuetype = Story AND labels = customer-bug").
Nesting
The quoted JQL of subtasksWhere and parentsWhere is ordinary JQL run by Jira, so it may call any JQL function, including this pack's: issue in subtasksWhere("issue in addedToSprintAfterStart(\"Team Rocket Sprint 14\")").
How current a result is
Jira calls a function once for each new list of arguments, stores the answer, and reuses it for every user. The final search is filtered by the searching person's own permissions, so nobody sees an issue they could not see anyway.
- The app updates some of its stored answers every five minutes, as many as the requests Jira allows it, so each one is updated about every 40 minutes and a search can be an hour or more behind a sprint change. On a site with many hundreds of stored answers one update cannot reach them all, and some answers are then older still.
- If an update cannot read Jira, the stored answer is kept rather than replaced with an error.
- An error is not kept the same way: Jira asks the app again whenever a board, gadget or search loads a filter whose function answered with an error. Once the cause is fixed (for example, one of two sprints with the same name is renamed), the next load shows the issues.
- The first search with a new list of arguments waits while the app reads Jira: about 4 to 9 seconds in issue search on a test site with about 2,700 sprints. Later searches with the same arguments use the stored answer.
Limits
- Jira lets a function return at most 1,000 values (issues, parents or sprints). Over that, the function returns no results and an error that names the limit; it never returns part of the answer. The date functions count sprints, so an open-ended range can pass the limit on a site with many sprints.
- Jira gives a function 25 seconds. The app stops at 20 seconds with an error saying so.
- One call reads at most 10,000 issues; over that it returns an error asking for a narrower query.
- The quoted JQL of
subtasksWhereandparentsWhereis run as the app, not as the person searching, because Jira shares one stored answer between users. The returned issues are filtered by the person's permissions, but whether a parent is returned can depend on a child they cannot see. - Sprint names are matched exactly, ignoring case. If two sprints share a name, the function asks for the id. Dates are in UTC.
- Error messages appear in issue search, under "JQL error". REST and API callers (for example
POST /rest/api/3/search/jql) get HTTP 400 with Jira's generic text instead, "Your query couldn't be processed. Make sure it's valid and try again later.", whatever the cause. Run the same query in issue search to read the reason.
Known limitations
- Boards and dashboard gadgets do not show the app's error messages. If a function in a board's filter cannot answer, for example because a sprint name now matches two sprints, a sprint was deleted, or a date range matches more than 1,000 sprints, the board keeps showing its loading placeholders and gives no message. A Filter results gadget on the same filter shows only Jira's own text: "The filter configured for this gadget could not be retrieved. Please verify it is still valid on the issue navigator." Jira draws both screens, and an app cannot change them. To read the reason, open the filter in issue search, where it appears under "JQL error". An erroring gadget's header reads only "Filter results", without the filter's name, so open the gadget's settings to see which filter it uses.
- A board filter can start failing some time after it was set up, with nothing typed wrong: someone gives another sprint the same name, a sprint is deleted, or a project grows past the 10,000 issues a call reads. The function then answers with an error rather than an old or partial list. In board and gadget filters, give a sprint by its id (
addedToSprintAfterStart(231)), which keeps working when a sprint is renamed or another sprint gets its name, and give date ranges both ends. - The first time a board or gadget meets a list of arguments Jira has not stored yet, it waits as long as issue search does: about 11 seconds for a sprint function on the test site. Later loads use the stored answer.
- A JQL function cannot add columns to search results, so sprint start and end dates are not shown as columns.
Questions
- My board shows loading placeholders and never loads. A function in the board's filter answered with an error. Open the board's filter in issue search to read the reason under "JQL error", fix it (for example, give the sprint's id instead of a name that now matches two sprints), and reload the board.
- A gadget says "The filter configured for this gadget could not be retrieved". The same: open the gadget's settings to see which filter it uses, then run that filter in issue search to read the reason.
- I changed a sprint and the search does not show it yet. Stored answers are updated about every 40 minutes and can be an hour or more behind. Search again after that.
- My search through the REST API fails with "Your query couldn't be processed". Jira gives API callers its own generic text. Run the same JQL in issue search to read the app's message.
- Why does an open-ended date range fail on our site? It matched more than 1,000 sprints, Jira's limit for one function. Give both ends of the range.
- Can someone see issues they have no access to? No. Jira filters every search by the searching person's permissions. The quoted JQL in
subtasksWhereandparentsWhereruns as the app, so whether a parent is listed can depend on a child the person cannot see, but the child itself is not shown to them. - Does it work in team-managed projects? Yes,
subtasksWhereandparentsWherework in company-managed and team-managed projects.