How To Report A Bug So It Actually Gets Fixed :: The Tymscar BlogHow To Report A Bug So It Actually Gets Fixed<br>2026-08-23Oscar Molnar7 min read (1486 words)<br>#technical<br>#development<br>#java<br>#kotlin<br>#jvm<br>#debugging I wanted to make a blog post like this for a long time, because it’s something that I wish I could find more of myself. I think one of the things that helps us most in our careers as software engineers is knowing how to debug problems, how to reproduce them, and how to report them.<br>What prompted me to write this was watching this awesome video from Kovarex, the founder of Factorio, where he goes through a bug report and tries to fix it. I thought the bug report was written pretty well, and I thought it might be helpful to show how I went about writing a bug report like this myself, and what the thought process was.<br>Last year the logs of a production service I was running started filling up with<br>LEAK: ByteBuf.release() was not called before it's garbage-collected.<br>Thousands of times. You instantly think it’s something to do with some sort of memory leak, considering it’s spammed by the GC, but let me explain how I got from here to Microsoft shipping a fix in a few weeks.<br>Own the bug#<br>1. Always assume you are wrong.<br>We all write code. Sometimes the same code changes every day, especially if it’s a feature we are actively working on. Netty, on the other hand (the networking library that the Azure OpenAI SDK my service uses is built on, and where that LEAK line comes from), is run by thousands of companies. Surely the issue is your code.<br>This is where I spent most of my time on this issue, trying to see if it was. That’s not wasted time, because if it ends up being your issue, you fix it and go on with your day. If it’s not your issue, well, then you get to participate in what I think is the most wholesome part of software development, which is bug reporting.<br>2. Make it deterministic.<br>If something is random, it usually means you haven’t really found what the issue is.<br>The thing with Netty is that it only reports a leaked buffer when the garbage collector collects it. So even if the actual leak is steady, in the logs it looks like random bursts, because you need to wait for the garbage collector to actually get to it.<br>So my reproduction runs a hundred concurrent requests and calls System.gc() every single time one fails. Normally this is something you would never, ever do in production. But for a reproduction of a bug, it’s basically the spotlight that shows you where something happens.<br>3. Bisect versions, just like you do with commits.<br>If you don’t know about git bisect, well, stop reading this blog post. I think that would be a much better use of your time. It lets you quickly find where a commit has gone awry by always jumping midway between commits, so you can narrow down where the issue appears.<br>What I wanted to do here was something similar, but instead of jumping between commits, I wanted to jump between versions. So I had my reproduction code, something super simple, and then, using the exact same app, the same SDK and everything, I jumped between versions until I got to the border between one of them working and one of them not working. In my case, reactor-netty-http version 1.1.23 was clean and working, and 1.1.24 leaked. That was the issue.<br>4. Shrink it into a public repository.<br>There are two reasons you want to do this. Usually when you have an issue in production, there’s a lot of private data sitting next to it that you wouldn’t necessarily want to share with everybody online. That’s the first reason. The second is that the more complex your reproduction environment is, the harder it becomes to actually pinpoint the bug. So you want to create a repository that you can share with the maintainers of the project, one that is as small as possible but still reproduces the bug.<br>In my case I created a Gradle project with a single test, with exact pins of the versions that started having the issue. That proves the bug without you having to trust me, and it proves that it’s not my app that is actually bugged, but rather something upstream. It later became the test that the fix was verified against, because if you have this reproduction inside of a public repository, you can always check whether it still fails after the fix has been deployed.<br>Report it#<br>5. File where the evidence points.<br>Now comes the fun part. In my case I filed it with reactor-netty, because the bisecting between reactor-netty versions is what showed me where the bug was. I made an issue with them, but it was closed, because it wasn’t actually their fault.<br>They explained it to me pretty clearly, and that to me was a huge boon. I could then take that and go to the actual source of the issue, which in this case was the Azure SDK for Java. The connection between the two is that the Azure SDK is built on top of reactor-netty.<br>6. Do the archaeology.<br>This...