JQL WAS and CHANGED: Search Jira History, Tested

On this page
  1. WAS and CHANGED in one minute
  2. Now versus ever
  3. The questions, with the queries
  4. Six fields, and the error for the rest
  5. Three ways history search goes quietly wrong
  6. Make it a habit
  7. How we tested

The retro question is “how much did we finish in October, and how much came back?”. The Jira board only knows where things are now. The answer lives in each work item’s history, and JQL can read it with two operators: WAS for “did it ever hold this value” and CHANGED for “did it move”.

We ran every query on this page on our Jira Cloud test site on 13 November 2026, against 162 work items with a few weeks of real history behind them, and counted what each returned.

Short answer: status CHANGED TO Done DURING (startOfMonth(-1), endOfMonth(-1)) is what was finished last month; status CHANGED FROM Done is what was reopened; status WAS "In Progress" ON "2026-11-10" is what was in progress that day. History search works on six fields only: assignee, fix version, priority, reporter, resolution and status. WAS EMPTY does not find work items that were empty from the start.

WAS and CHANGED in one minute

OperatorAsksExample
WASdid the field hold this value, now or before?status WAS "In Progress"
WAS INany of these values?status WAS IN ("In Review", "In Progress")
WAS NOTnever this valuestatus WAS NOT "In Progress"
WAS NOT INnever any of thesestatus WAS NOT IN ("In Progress", "In Review")
CHANGEDdid the field move?priority CHANGED

Both take the same time and people filters, called predicates:

PredicateExample
AFTERstatus CHANGED AFTER -7d
BEFOREstatus WAS "In Progress" BEFORE "2026-11-11"
ONstatus WAS "In Progress" ON "2026-11-10"
DURINGstatus CHANGED TO Done DURING (startOfMonth(), now())
BYstatus CHANGED BY currentUser() AFTER -7d
FROM / TO (CHANGED only)status CHANGED FROM "To Do" TO "In Progress"

DURING takes exactly two dates. status WAS "In Progress" DURING (-7d) fails with The DURING predicate must be supplied with exactly 2 date values. Write DURING (-7d, now()), which Jira accepts.

Now versus ever

WAS includes the present. Atlassian: it finds work items “that currently have or previously had the specified value”. On our site:

Bar chart of work items on our Jira Cloud test site. In Progress: 17 now with status = In Progress, 29 ever with status WAS In Progress. Done: 22 now, 27 ever with status WAS Done. Unassigned: 56 now with assignee is EMPTY, but only 1 with assignee WAS EMPTY, because WAS sees values recorded as changes and these work items were unassigned from the start. Source: our searches, 162 work items.

The status bars make sense: 29 work items have been in progress at some point, 17 still are. The status a work item was created with counts too: all 48 work items in To Do matched status WAS "To Do", and only 9 of them had ever changed status.

The empty value does not work the same way. 56 work items had no assignee, yet assignee WAS EMPTY found exactly one: the only one whose assignee had been removed. The other 55 were created without one, and nothing in their history says “empty”. For the present, use assignee is EMPTY; for “was unassigned at some point”, JQL has no reliable answer.

The questions, with the queries

What did we finish last month?

status CHANGED TO Done DURING (startOfMonth(-1), endOfMonth(-1))

CHANGED TO Done counts moves into Done, so a work item reopened and closed again counts once in the result (JQL returns work items, not events). For this month so far, status CHANGED TO Done DURING (startOfMonth(), now()) found 22 on our site; since the start of the week, status CHANGED TO Done AFTER startOfWeek() found 15.

Last month, October, that query found 5 on our site. If your workflow has several done statuses, list them: status CHANGED TO (Done, Released) returned the same 27 as (status CHANGED TO Done OR status CHANGED TO Released). Or count resolutions instead: resolution CHANGED found 31 for us.

What was reopened?

QueryFound
status CHANGED FROM Done5, every move out of Done
status CHANGED FROM Done TO "In Progress"2, straight back to work

Add AFTER -30d for a monthly quality number, and project = PAY to keep it to one team.

What skipped a step?

statusCategory = Done AND status WAS NOT "In Progress" found 25 of our 31 done work items: they were closed without ever being in progress. With review added, status WAS NOT IN ("In Progress", "In Review") AND statusCategory = Done found 24. On a real team this is the list for a “why did these skip review?” conversation, or proof that the board’s columns no longer match how people work.

What was in progress on a given day?

QueryFound
status WAS "In Progress" ON "2026-11-10"14
status WAS "In Progress" BEFORE "2026-11-11"22
status WAS "In Progress" DURING ("2026-11-09", "2026-11-12")22

ON with a date is the closest JQL gets to “what was on the board last Tuesday”.

What started this sprint?

status CHANGED FROM "To Do" TO "In Progress" found 15; status CHANGED TO "In Progress" AFTER -14d found 14. Pair it with sprint in openSprints() to keep it to the running sprint.

Who moved what?

QueryFound
status CHANGED BY currentUser() AFTER -7d20
status WAS "In Progress" BY currentUser()29
assignee CHANGED AFTER -7d18 reassigned in a week
assignee WAS currentUser()22, against 20 assigned to me now
priority CHANGED FROM Medium TO High3 escalations

BY takes a person: currentUser() or an account ID, or several in brackets.

Six fields, and the error for the rest

Atlassian’s operators page: WAS “can be used with the Assignee, Fix Version, Priority, Reporter, Resolution, and Status fields only”. Everything else fails. On our site sprint CHANGED, labels CHANGED, duedate CHANGED, summary CHANGED and statusCategory CHANGED all returned:

History searches do not support the 'sprint' field.

(with the field’s name). In the REST search API, which apps and scripts use, the same queries came back as Processing of your search request has failed. Enable validation to ensure that your request is correct. That is the message to recognise when an app reports a broken saved filter.

So there is no JQL for “moved between sprints”, “due date was pushed” or “status category changed”. Sprint history needs the sprint report or an app; due-date changes need the work item’s history tab or an export.

Three ways history search goes quietly wrong

  1. Typos return nothing. status = "In Progres" fails with The value 'In Progres' does not exist for the field 'status'. status WAS "In Progres" passes Jira’s check and returns 0: old values are not checked, because a status may have existed once.
  2. Renamed statuses. Atlassian notes that WAS “will match the value name … which was configured in your system at the time that the field was changed”, and the value’s ID too. If your workflow renamed “In Dev” to “In Progress”, search for both names.
  3. Very long histories. For a work item with more than 10,000 changes, WAS only searches the most recent ones (Atlassian’s operators page). Rare, but it happens on automation-heavy items.

Make it a habit

Saved as filters, the queries above become dashboard gadgets: finished this month, reopened this month, closed without review. For the date half of each query, startOfMonth(-1) versus -30d and why -2d is not “since the day before yesterday”, see JQL dates. Paste a history query into the free JQL builder and it warns when a field does not support WAS or CHANGED.

If writing these by hand gets old, our app JQL Blocks has blocks for “created, resolved or changed status during the current sprint, the previous one, or the last N”, and the JQL cheat sheet has every other field and operator.

How we tested

  • Site: our Jira Cloud test site on the Standard plan, 162 work items with history from October and November 2026.
  • When: 13 November 2026, around 11:00 CET. Relative predicates (-7d, startOfWeek()) depend on the moment you run them.
  • How: each query through POST /rest/api/3/jql/parse?validation=strict, then counted with POST /rest/api/3/search/approximate-count.
  • Reference: Atlassian’s JQL operators page (WAS, WAS IN, WAS NOT, WAS NOT IN, CHANGED), read the same day.

Frequently asked questions

How do I search for a status change in JQL?

Use CHANGED: status CHANGED FROM "To Do" TO "In Progress" finds every work item that made that move. Add AFTER, BEFORE, DURING, ON or BY to narrow it, for example status CHANGED TO Done DURING (startOfMonth(), now()).

What is the difference between WAS and CHANGED in JQL?

WAS asks whether a field held a value: now, or at some point in the past. CHANGED asks whether the field moved, optionally FROM one value TO another. status WAS Done includes work that is done today; status CHANGED TO Done counts the moves to Done.

Which fields support WAS and CHANGED?

Six: assignee, fix version, priority, reporter, resolution and status. Others fail. sprint CHANGED on our site returned "History searches do not support the sprint field"; labels, due date, summary and statusCategory gave the same error.

How do I find issues that were reopened in Jira?

status CHANGED FROM Done TO "In Progress" finds the ones moved straight back to work; status CHANGED FROM Done finds every move out of Done. Use your own status names: a workflow might call it Closed or Resolved.

Why does assignee WAS EMPTY miss unassigned issues?

WAS only sees values recorded in the history. A work item created without an assignee has no history entry saying "empty", so it is not found. On our site assignee is EMPTY found 56 and assignee WAS EMPTY found 1. Use assignee is EMPTY for the present.

Keep reading