Question

Question:

What is the proper way to address a bug that an end-user thought was a feature?

Elaboration:

I'm guessing that if a large percentage of users expected it as a feature, it should be left "unfixed" or "fixed" to be more stable? However, what if a very small percentage of users expect it to be a feature... say 0.1% or 1%, and this bug must be fixed.

Theoretically, since this is a minor bug fix it can qualify as PATCH as considered by semantic versioning: x.y.Z. However, since it does break backwards compatibility (even just for a few users) it should be a MAJOR increase: X.y.z. Correct? Could it still qualify as a PATCH (since it was not intended as a feature) as long as it's documented?

EDIT: In this specific case, it's a bug in an API of an internally-used library that other developers use.

Was it helpful?

Solution

I'm guessing that if a large percentage of users expected it as a feature, it should be left "unfixed" or "fixed" to be more stable?

Does the bug add value? If so, it's more of a feature. Sometimes a "bug" can end up as a value-add "feature."

It's hard to really answer this conclusively because every single situation will be different.

In this specific case, it's a bug in an API of an internally-used library that other developers use.

In this case, I would include a fix as part of your next breaking change with respect to backwards compatibility. You can't really just do this consistently in most environments and there's probably a schedule/timeframe for this.

As a developer the last thing I want to deal with is an API which has incorrect or inconsistent behavior. Bugs are considered this.

At the very least, create some sort of "known bugs with current version" document/wiki internally and so you can ensure all your internal users know the functionality is bug-like. Hopefully you have enough tests covering the areas where people are using the bug-as-a-feature so you will see where/when things break when/if you fix the bug.

OTHER TIPS

I'd recommend making it more stable. Users are the canonical source of what your software does. If they want it, and have come to rely on it, I'd think twice about yanking it.

A good example of this is the "Skiing" mechanic in the video game "Tribes". Originally a bug in how the physics engine handled jumping on a hill, it ended up one of the core game mechanics. You can read a bit more about it here, if you're curious.

Since the bug is in a library, here is another approach that you can take:

  1. Make a clone of the erroneous library function. In many cases people just append a 2 to the function name in these cases, but, if you have other changes that you would like to apply to the interface of that function, you might also give it a completely different name.

  2. Fix the bug in the clone only (and implement all other interface changes that you want while you're at it).

  3. Declare the original function as deprecated.

  4. Remove the original function in some upcoming major release.

This approach is especially useful for functions whose interface is fundamentally broken: You don't break user code right away, but you give due warning to whoever relies on the broken code to transition to using the fixed code. And even if people don't heed the warning, they can't really blame you once you actually remove the broken function.

In this specific case, it's a bug in an API of an internally-used library that other developers use.

If those other developers thought the behaviour to be a feature, it is likely they have used it and have build working software upon it. Fixing the bug will probably break their existing code, and they will blame you for this. This makes fixing the bug a trade-off, and you have to consider

  • is it really important to fix the bug, for example because there is a high risk of letting users of your API crash their applications in case the bug is not fixed? Or is this just about consistency of the API?

  • or is it more important to keep the existing software stable, and your library backwards-compatible?

The answer to the question is not always simple, you have to take the number of possible users of your API into account, the potential amount of work they will have to change their software, the amount of software which will break if you change your API, but also the risks of what might happen if you do not fix the API.

Just because you document the bugfix change in a "list of breaking changes in your next major release" does not make your customers happy - if you do this, there should be at least some bullet proof reasoning why you could not let the API as it was before. Often keeping backwards compatibility is more important than fixing a bug. So fix it only if you can estimate the impact on your user base and their software and you are sure you are not going to produce unreasonable efforts for them when they try to update to your latest library release. And if you do not have enough information to make a good estimate on this, it will probably be better not to change the behaviour.

(And yes, if you are going to make an API change which is not backwards compatible, your version numbers must express this clearly, does not matter if you name it a "bugfix" or not).

Embrace it. It can make your entire your product.

GunZ: The Duel (an online game) had a bug that you could exploit and constantly abuse to change pretty much the entire gameplay (called K-Style; look it up on YouTube). It made the whole game way more challenging; it took skill and made it just amazing and fun.. so fun that even the moderators openly used it as their main play style.
It's what made the game.
I didn't play in years but to this day, as a gamer, it's one of my favorite games of all time because it's so skill-based and just so fun, and all of this awesomeness just because of a bug.

They did fix it eventually, but people hated that so much that the devs seriously bugged it back.

So my answer is stabilize and maintain it (refactor if needed).


That beautiful story being said, I don't think the same answer applies for anything that doesn't have a direct advantage. If your bug causes an event which causes the advantage, it will usually be smarter to fix the bug, and find another way to achieve whatever it could. If it's out of scope, consider leaving it out just for being out of scope, or create another module (maybe a small one) to introduce it. Basically: do not violate single responsibility principle.

Licensed under: CC-BY-SA with attribution
scroll top