Bug Bashes are a Smell

The other day, I was in a Slack discussion with some of the good folks at Test Double. The topic of bug bashes came up, and the conversation was rich. People brought thoughtful perspectives and experiences, and the discussion left me reflecting on what bug bashes say about the systems we work in. That exchange led me here, to write this article. Not because I want to scold anyone for running bug bashes, but because I think what they represent is more interesting than the practice itself.

The punch list house

Let’s start with a metaphor. Imagine you’re building a house. From the very beginning, the plan is to have a big punch list party at the end. Everyone knows this is coming, so during construction, corners get cut. A little misaligned trim here, a squeaky floorboard there. Why worry? We’ll catch it on the punch list. Then comes the final walk-through, and sure enough, the list is long and painful.

Bug bashes are the software equivalent. They signal that we’ve assumed defects are inevitable and set aside special time to deal with them at the end.

The belief beneath the practice

This is where expectancy effects and confirmation bias come into play. When we believe something is inevitable, we behave in ways that make it more likely to occur. If you believe people will be rude to you, you interact defensively and increase the chances of rudeness. If you believe bugs are unavoidable, you invest in catching them late rather than preventing them early. Then, when the bugs appear, the belief feels confirmed.

So bug bashes aren’t proof that a team cares about quality. They’re proof that the team doesn’t yet trust its system to produce quality without extra rituals. That’s a different thing entirely.

What the belief produces

When an organization operates with the assumption that bugs will escape, it quietly invests in late discovery and triage. Bug taxonomies and prioritization schemes. Ritualized bug hunts before a release window. Hardening phases. QA positioned as gatekeepers. Each of these feels like addressing the problem, but really they are built on a belief that quality cannot be built in from the start.

A different way of working

The alternative is not glamorous. It’s daily, intentional work. It’s building quality in, instead of inspecting it in. It looks like this:

Bring QA into design and lead with tests (Validate before, during, and after)

I don’t care much anymore about whether you call it TDD, BDD, or Specification by Example. Arguments over which is “best” are mostly wasted energy. What matters is leading with tests. Think about how you will validate a change before you make it. Write clear acceptance criteria that reflect that thinking. Seriously consider writing your tests first, or at the very least, write them as part of the real-time development process. Not a week later. Not after you’ve merged. Right then.

Reduce the change surface (Create simple things in small steps)

Keep changes small. Ship them often. Every extra line of code, every additional branch of logic, every integration point is another chance for something to go wrong. Reducing the change surface isn’t just about writing less code, it’s about structuring the work so that fewer things can break at once.

Compose with care (Be meticulous about composition)

Systems that are tightly coupled and loosely cohesive breed defects. Systems that are well-composed reduce them. When like things are kept together and unlike things are separated, understanding grows. Testing gets easier. Recovery is simpler. Quality isn’t just about testing, it’s about how we structure the work itself.

Work together every day (Work together)

Bug bashes try to simulate collaboration by pulling people together in a big event. Real collaboration is quieter and more constant. Designers, product folks, QA, and developers working side by side. Pairing, ensembles, shared ownership of quality. The more often people work together, the fewer surprises they create for each other.

Ship small and often (Release ridiculously often)

The less you ship at once, the less there is to go wrong. Frequent, small releases reduce the blast radius when things do go wrong. They also build confidence. When your system is delivering continuously, you don’t need to stop the line for a big bug hunt. You already know what shape the work is in.

Automate what you can (Favor automation over documentation)

Checklists and bug bash rituals are brittle. Automated tests, CI/CD pipelines, and production telemetry give you real, repeatable feedback. They let you see the truth in minutes, not days.

A story of change

At a former client, a software company, we put in place a zero-new-defects policy. The first couple of weeks were rough. Defects still slipped through, and teams responded by adding bug bashes before every release. That was better than pushing broken code to production, but it was still treating the symptom. The manager of the team insisted there was no other way and asked repeatedly that I simply trust him to do his job. Eventually, I moved him out of leadership and put in someone who had experience with building quality in from the start. Almost immediately, production defects went to zero.

At another client, a large manufacturer, we had the chance to start fresh on a greenfield project. From the very beginning, the team agreed: zero escaped defects. We defined “escaped” as any issue we couldn’t immediately roll back. This definition changed everything. It meant we thought about recovery with every deploy. We designed features with rollback paths in mind. We built monitoring so we could see failures quickly. We automated deployments so rollbacks were safe and routine. That project ran for over two years in production, managing a critical piece of order entry, without a single escaped defect. Not one. For all I know, that has held true in the several years since I moved on from the team. The work wasn’t magic. It was simply a team holding itself to a different belief about what was possible, and then building the system to make that belief real.

Objections I hear

“Bug bashes build camaraderie.”
Sure, camaraderie matters. But real camaraderie comes from daily co-creation, not one-off rituals. Keep the pizza, skip the bug bash, and collaborate while building.

“We need a final safety net.”
Safety nets are good, but they belong in automation and observability, not in calendar events. Trust repeatable checks and small releases over last-minute hunts.

“Our context is messy.”
All contexts are messy. Start with one story. Bring QA into the design conversation. Lead with tests. Ship it small. Notice the change in confidence. Let those results pull you forward.

Closing thought

Bug bashes aren’t proof that you care about quality. They’re proof that you don’t yet trust your system to deliver it. That’s not a failure of character. It’s simply a signal of where you are today. And it’s a place you can move beyond. Quality isn’t something you inspect in at the end. It’s something you build, every step of the way.

Further Reading

  • W. Edwards Deming, Out of the Crisis

  • Jez Humble & David Farley, Continuous Delivery

  • Kent Beck, Test-Driven Development: By Example

  • Donald G. Reinertsen, Principles of Product Development Flow

Related Behaviors