+1 to ashes999 for focusing on the root cause, but characterizations like:
- Didn't follow the coding conventions
- Bad coding logic
- Fix for another bug broke this bug
- Third-party library's bug
Tend to be so specific that over time, you have too many categories to be helpful. On some projects (but not all) I have categorized bugs by Phase - sort of a loose term to try to capture when in your project life cycle the defect was injected.
Having a drop down box allowing you to select from Requirements, Design, Code, Integration is all I have ever needed. If you are really hardcore you could split this into 2 parts: Phase Injected and Phase Detected. The basic idea here is defect phase containment - there is some good evidence that shows that the longer it takes you to find a defect, the more expensive it is to fix. For example, a requirements error is cheap to resolve in the while you are working on your requirements, but may cost plenty after you've released your product.
Even if you don't do all the fancy level 5 CMMI analysis, knowing what phase you are injecting problems in is extremely helpful. Like any other measurement, you should create it with a specific goal in mind - knowing that most of your defects are ultimately related to requirements or design or coding or whatever helps focus you attention on where the process fix should be. Otherwise, you may be tempted to add more and more testing. This is potentially the least efficient way to address the problem.