A bug marked "Fixed" that goes directly to "Closed" without passing through "Verified" is how regressions reach production. A bug sitting in "Assigned" for three sprints is a ticket no one is watching, not a fix in progress. This article maps every state in the bug lifecycle, who owns each handoff, and what to do when bugs stall, get marked Won't Fix, or come back after you've already verified them.
The standard states and who owns each one
Every bug tracking system has its own labels, but the underlying states are universal. Knowing who holds responsibility at each stage tells you when to act and when to wait.
New is the moment you file the ticket. Nothing has happened yet. The bug exists on paper but no one has committed to fixing it. Your job here is to make the report airtight: clear title, exact reproduction steps, expected vs actual, severity, attachments. A poorly written "New" bug will sit in triage limbo because whoever picks it up can't reproduce it. Assigned means someone on the development team owns the ticket. It doesn't mean they've looked at it. It doesn't mean they agree it's a bug. It means a name is attached. This state is where bugs go to age. More on that later. In Progress means active work is underway. A developer is reproducing, investigating, or writing a fix. As QA, your job here is availability: if the developer has questions about the reproduction environment or edge cases, answer them fast. Delays here add sprint drag. In Review means the fix is written and waiting for a code review or peer approval. Some teams combine this with a "Ready for QA" state that signals the build is available for verification. Know which workflow your team uses, because the distinction matters for your sprint planning. Fixed (or "Ready for Testing") is the handoff back to you. The developer believes the problem is resolved. Now it's your turn. Verify against the original reproduction steps exactly. Don't improvise a new test path. Confirm the specific scenario that was filed is resolved first, then expand to related cases. Verified means you've confirmed the fix works as described. The original defect is gone. You've checked the obvious regression paths. This state is your sign-off. Closed means the verified bug is accepted and done. In most teams, this is either done by the QA lead, scrum master, or happens automatically when the sprint closes. A bug should never go from Fixed to Closed without passing through Verified. Skipping that step is how regressions reach production.The Rejected state means the team decided the reported behavior is actually correct. Either the expected result in the bug report was wrong, the behavior is intentional by design, or the reporter misunderstood the requirement. Rejected doesn't mean you were careless. It's a legitimate outcome. Document why it was rejected so future testers don't re-file the same ticket.
Deferred means the bug is real and acknowledged, but not being fixed in this sprint or release. It goes into a backlog. Whether it ever gets fixed depends on how well you argue for it. Won't Fix is permanent Deferred. The team has decided this defect is not worth the effort to resolve. Sometimes this is the right call. Sometimes it isn't. How you respond determines whether it becomes a problem later.Won't Fix and Deferred: how to argue without losing
Here's a real scenario. You file a bug: "On the checkout page, applying a discount code after selecting a shipping method resets the shipping selection to the default option." PM triages it and marks it Deferred. The comment: "Low impact, edge case, not enough users hit this."
This is where most QA engineers either accept it silently or argue emotionally. Neither is effective.
The better approach is to reframe the conversation around data and user paths, not your personal opinion. Ask: how many checkout sessions per week include a discount code? Does your analytics show abandonment spikes at that step? Is the shipping reset causing orders to go to the wrong address?
If you don't have that data, say so and ask who can pull it. "I'd like to understand the actual frequency before we close this. Can we pull checkout funnel data for the last 30 days?" That's a reasonable request, not a fight.
If the PM still wants to defer after seeing the data, document the risk explicitly in the ticket. Write: "Risk accepted: users applying discount codes may unknowingly select wrong shipping method. Impact: potential misfulfillment." Then close it. You've done your job. If the issue escalates post-release, there's a clear record that the risk was raised and documented.
Reopening bugs without creating drama
A bug comes back. You verified it two weeks ago, it's sitting in Closed, and now the same symptom is appearing in production. You need to reopen it, but the developer who fixed it is going to notice, and nobody likes seeing their work called back.
The rule is simple: reopen only when you can demonstrate the original scenario is failing again. Not "something similar," not "could be related." The exact original reproduction steps, same environment, same result.
When you reopen, add a comment before you change the state. Include: the date you're reopening, a new screenshot or recording, the exact reproduction steps you ran (even if identical to the original), and whether you're seeing the same symptom or a new variation. If it's a new variation on the same component, that's a different bug, not a reopened one.
Say you verified that the discount-code-resets-shipping bug was fixed in v2.8.1. In v2.8.3, after a new feature was shipped around the checkout flow, the bug is back. You reopen it, attach a recording, and note: "Regression introduced in v2.8.3. Verified fix present in v2.8.1 build, no longer present in current build. Reopening with new recording."
That framing does two things. It acknowledges the original fix was valid. It points toward a new regression rather than implying the developer didn't fix it properly the first time. That distinction matters for the working relationship.
Duplicate bugs: identification and graceful merging
On any active product, multiple testers can file the same bug independently, especially around features that just shipped. Identifying duplicates early saves triage time and prevents split developer effort.
Before filing a new bug, search your tracker for the symptom. Search by component first (checkout, login, upload), then by keywords from the error message or behavior. If you're working in Jira, use the "Similar Issues" panel: it searches automatically when you're creating a ticket.
If you find a duplicate after filing, mark yours as a duplicate of the original (not the other way around, unless yours is clearly more detailed). Add a comment: "Marking as duplicate of PROJ-144. Same reproduction path, same symptom. Adding my screenshots to the original ticket in case they help."
Then go to the original ticket and actually add the value from your duplicate. Maybe your version has a cleaner video or a different browser version that reproduces it. That information is useful even if your ticket is closed as duplicate.
One thing to avoid: merging bugs that look the same but aren't. If two tickets have the same error message but different triggers, they may be two separate defects. Verify the root cause before merging. A developer who fixes one bug based on a merged report and misses the second trigger is not happy to discover that in production.
Bug aging: what to do when Assigned means nothing
You've filed a bug. It gets triaged, assigned to a developer, and then nothing happens for three sprints. The sprint review comes and goes, no mention of it. The ticket sits in "Assigned" like a fossil.
This is one of the most common QA frustrations, and the correct response is visibility, not nagging.
First, look at the bug yourself. Is the priority accurate? Is it still a blocker on anything? If the context changed and the bug is now less relevant, adjust the priority and add a comment. A low-priority bug sitting for three sprints is less alarming than a medium one.
If the priority is accurate and the bug still matters, bring it into the sprint review explicitly. Not as a complaint, but as a risk item. "We have PROJ-188 sitting in Assigned for three sprints. It affects the CSV export feature, which our enterprise users flag frequently. I want to flag it for the next sprint before it becomes a customer escalation."
Most aged bugs die because nobody re-raised them. Your sprint review and backlog refinement meetings exist for exactly this.
If the bug genuinely should not be fixed in the current roadmap, ask for it to be formally Deferred with a documented reason. An honest Deferred is better than a zombie Assigned ticket: it gives the team a clear signal and prevents false impressions of the open bug count.
Jira vs Linear vs GitHub Issues in 2026
The workflow logic above applies everywhere, but the tools you're working in have meaningful differences in how they implement state transitions.
Jira remains the standard in mid-to-large enterprise teams. In 2026, it's on its third generation of workflows since the company-managed vs team-managed split. Bug states in Jira are fully customizable, which means every team uses a different subset of the states described above. Your first week on a new Jira-using team should include understanding exactly what their workflow states mean. Don't assume "In Progress" means a developer is actively working. In some Jira setups it means "acknowledged but not started." Check the workflow documentation or ask directly. Linear is now standard in most early-stage and growth-stage startups. It uses a simpler state model: No Status, Backlog, Todo, In Progress, In Review, Done, Cancelled. There's no dedicated "Verified" state by default: QA verification either happens inside "In Review" or teams add a custom state. If you're joining a Linear team, check whether they have a QA verification step in the workflow. If they don't, propose one. A ticket going from "In Review" to "Done" without a tester signing off is a pattern that eventually ships unverified fixes. GitHub Issues is common on open-source and developer-tooling products. Its native state model is just Open and Closed, with labels for everything else. Most teams that do structured QA on GitHub Issues use labels likestatus: ready for QA, status: verified, and milestones to track release scope. The friction here is that GitHub Issues has no enforced workflow: discipline is entirely manual. On a team that lacks that discipline, bugs move from Open to Closed without any verification step.
The common thread: whatever tool you're in, understand the actual workflow your team uses, not what the tool supports by default. The lifecycle states exist regardless of which labels your tracker uses.
Metrics: the numbers that tell you if the process is working
Tracking bug states individually is useful. Tracking patterns across all bugs tells you whether your quality process is healthy.
Defect escape rate measures the percentage of bugs found in production versus bugs found before release. If your team is finding 30% of bugs after release, the testing process isn't catching enough before the software ships. The formula: (bugs found post-release) / (total bugs found) × 100. A healthy rate for most teams is under 15%. If yours is higher, look at where in the development cycle bugs are being introduced and where testing coverage ends. Mean time to resolve (MTTR) measures the average time from a bug being filed to it being closed. A rising MTTR signals one of three things: the team is understaffed for the bug volume, bugs are being filed at a lower quality (taking longer to triage and reproduce), or specific components are generating outsized defect density. Track MTTR by component to find the hotspots. Open bug aging report is exactly what it sounds like: a view of every open bug sorted by how long it's been open, grouped by state. The useful version of this report segments by state. A pile-up in "New" means triage is backed up. A pile-up in "Assigned" means developers aren't picking bugs up. A pile-up in "Fixed" means QA isn't verifying fast enough. Each state tells a different story about where the bottleneck is.These three metrics together give you a reasonably complete picture of bug lifecycle health. Run them monthly, not just at the end of a release cycle.
How to apply this Monday morning
Go into your bug tracker and pull up every ticket assigned to you or filed by you that isn't in Closed or Won't Fix. For each one: is it in the right state? Is the priority still accurate given what you know about the current sprint? Are there any tickets that have been sitting in the same state for more than two sprints without a comment?
For every aged ticket, add a one-line comment today: either a status check if you need one ("Still relevant: export feature is still in scope, raising for next sprint review"), or an explicit request to Defer if it's no longer relevant ("Context has changed since filing: this screen was removed in v2.9. Recommending close.").
This single pass through your open bugs does three things: it clears your mental backlog, it gives the team accurate information about what's actually open, and it demonstrates that you're actively managing quality, not just filing tickets and moving on.
The bug life cycle is not bureaucracy. It's the mechanism by which a finding turns into a fix. Every state transition is a handoff, and every handoff needs someone paying attention to it. That's the job.
→ See also: The Anatomy of a Bug Report That Developers Actually Fix | Severity vs Priority: The Bug Triage Skill That Gets Junior QAs Promoted | How to Write a Test Case: Format, Examples, and Common Mistakes