DEV Community

greymoth
greymoth

Posted on

"I Found ~30 Mergeable OSS Bugs in a Day. They Were All the Same Shape."

Yesterday I shipped around 28 pull requests across real repos — zod, NestJS, Fastify, Scrapy, Pygments, others. Not spam. Not docs typos. Actual behavioral fixes that got merged or are pending review.

The method has a name now. I'm calling it sibling-leftover.

What sibling-leftover actually is

When a maintainer merges a PR that fixes something in one area, they're implicitly approving the intent. But if the fix touched only one of two symmetric branches in the code — and left the sibling untouched — there's a window. The maintainer already agreed the behavior was wrong. The fix pattern is already in-tree. You're not arguing a new position; you're completing a sentence they started.

The leftover sibling is almost always a bug. Not always a serious one. But it's real.

Two concrete examples

zod #5945 → #6141

zod #5945 fixed cidrv4 validation. The PR landed. Closed. Merged. I looked at the diff and noticed cidrv6 sat right next to it in the same file, same logic shape, no corresponding fix. Opened #6141 targeting ipv6. The maintainer already understood the problem domain; the test pattern was already established. Merge friction: near zero.

NestJS #17188 → #17207

NestJS #17188 fixed a behavior in the WebSockets transport. Adjacent in the codebase: the microservices transport, same underlying issue. #17207. Same shape, different branch. I didn't have to explain why something was wrong — the merged PR did that for me.

This is the pattern. One fix → locate its symmetric counterpart → ship the mirror.

Why merge rates are high

Three reasons stack:

  1. Domain approval is already in. The maintainer accepted that this class of bug exists. They didn't reject the premise, they fixed it. You're not asking them to believe something new.

  2. Test infrastructure exists. The first PR almost always adds or modifies tests. Your fix can follow the same structure, in the same file, targeting the sibling case. Reviewers don't have to imagine what passing looks like.

  3. The diff is small and symmetric. A small, obviously correct diff in a familiar area is much easier to approve than a large refactor. Cognitive load for the reviewer is low.

How to run this yourself

Step one: find recently merged PRs in repos you care about. GitHub search — is:pr is:merged sort:updated — works. Filter by the last 30-60 days.

Step two: read the diff. Look for constants, enum branches, transport names, protocol variants, format handlers — anything where the code obviously has siblings. cidrv4/cidrv6. websockets/microservices. rgb/rgba. http/https. These pairs are everywhere.

Step three: grep the repo for the sibling. Confirm it has the same bug pattern. Write the fix following the same style as the merged PR — same variable naming, same test shape.

Step four: open the PR. Reference the original merged fix explicitly. "This mirrors #XXXX which fixed the same issue in [sibling]. Applying the same approach here." That sentence alone cuts review time.

What this is not

It's not cherry-picking trivially obvious things to pad a contribution count. Some of the fixes I found were non-trivial — the sibling had slightly different logic that required careful adaptation. A few I dropped because the behavior divergence was intentional and I wasn't sure.

The method is a search strategy, not a guarantee. You still have to read the code. You still have to understand why the original fix was correct. The frame just tells you where to look.

One thing I'll keep doing

Before I look for new bug categories, I now scan the merged PRs from the last week in repos I'm watching. It's maybe 20 minutes. The hit rate — "this fix has an unaddressed sibling" — is surprisingly high. My rough estimate from yesterday: about 40% of format/transport/protocol-related fixes leave something behind.

The bugs are there. They're findable. The method is repeatable.

Top comments (0)