If you’re going to be a humble programmer, you need to start with the assumption that every reported bug is your fault. This is a good principle, but what if it turns out the user did something stupid? What if it really is a third-party library that is buggy, not your code?

Even if a bug isn’t your fault it’s still your responsibility, and in this post I’ll explain how to apply that in practice.

First, discover the source of the problem

A user has reported a bug: they’re using some code you wrote and something has gone horribly wrong. What can the source of the problem be?

User error: they did something they shouldn’t have, or they’re confused about what should have happened.

they did something they shouldn’t have, or they’re confused about what should have happened. Environmental problems: their dependencies are slightly different than yours, their operating system is slightly different, and so on.

their dependencies are slightly different than yours, their operating system is slightly different, and so on. Third party bugs: someone else’s code is buggy, not yours.

someone else’s code is buggy, not yours. A bug in your code: you made a mistake somewhere.

A good starting assumption is that you are at fault, that your code is buggy. It’s hard, I know: I often find myself assuming other people’s code is the problem, only to find it was my own mistake. But precisely because it’s so hard to blame oneself it’s better to start with that as the presumed cause, to help overcome the bias against admitting a mistake.

If something is a bug in your code then you can go and fix it. But sometimes users will have problems that aren’t caused by a bug in your code: sometimes users do silly things, or a library you depend on has a bug. What then?

Then, take responsibility

Even if the fault was elsewhere, you are still responsible, and you can take appropriate action.

User error

If the user made a mistake, or had a misunderstanding, that implies your design is at fault. Maybe your API encourages bad interaction patterns, maybe your error handling isn’t informative enough, maybe your user interface doesn’t ask users to confirm that yes, they want to delete all their data. Whatever the problem, user mistakes are something you can try to fix with a better design:

Give the API guide rails to keep users from doing unsafe operations.

Create better error messages, allowing the user to diagnose mistakes on their own.

Make the UI prevent dangerous operations.

Add an onboarding system to a complex UI.

Try to remove the UI altogether and just do the right thing.

If a better design is impossible, the next best thing to do is write some documentation, and explain why the users shouldn’t do that, or document a workaround. The worst thing to do is to dismiss user error as the user’s problem: if one person made a mistake, probably others will as well.

Environmental problems

If your code doesn’t work in a particular environment, well, that’s your responsibility too:

You can package your software in a more isolated fashion, so the environment affects it less.

You can make your software work in more environments.

You can add a sanity check on startup that warns users if their environment won’t work.

If all else fails, write some documentation.

Third party bugs

Found a bug in someone else’s code?

Stop supporting older versions of a library if it introduces bugs.

If it’s a new bug you’ve discovered, file a bug report so they can fix it.

Add a workaround to your code.

And again, if all else fails, write some documentation explaining a workaround.

It’s always your responsibility

Releasing code into the world is a responsibility: you are telling people they can rely on you. When a user reports a problem, there’s almost always something you can do. So take your responsibility seriously and fix the problem, regardless of whose fault it is.