The SWE-bench benchmark was designed to answer a straightforward question: can a language model resolve real GitHub issues? You give the model a repository and an issue description, it produces a patch, and automated tests determine whether the patch works. The setup is clean, reproducible, and scalable. By that measure, progress has been impressive. Models that could resolve 5% of tasks eighteen months ago now regularly exceed 50% on the standard split.
A study published by METR in March 2026 asked a harder question: would these passing solutions actually be merged?
For a substantial number of them, the answer was no.
This matters because “passes the benchmark” and “passes code review” have been treated as roughly equivalent in how AI coding capability gets reported and discussed. Labs cite SWE-bench resolution rates to support claims about AI’s ability to do real software engineering work. The METR findings make clear that the benchmark measures one thing while the claims are about something broader.
What SWE-bench Actually Measures
SWE-bench takes issues from popular open-source Python repositories, includes the test case that the issue author or maintainer wrote to reproduce the bug, and scores a model’s solution on whether that test passes after the patch is applied. In the SWE-bench Verified variant, human reviewers additionally confirm that the test accurately reflects the issue, filtering out malformed or misleading test cases.
This is a genuine signal. A model that resolves 50% of SWE-bench tasks can read code, understand bug reports, and produce patches that satisfy the corresponding test conditions at a meaningful rate.
But it’s a partial specification of correctness. The test for a GitHub issue typically encodes one thing: does this specific case behave correctly now? It doesn’t encode whether the implementation approach is reasonable, whether new edge cases were introduced, whether the change is idiomatic given the project’s conventions, whether it makes the code harder to maintain, or whether it introduces security issues outside the test’s scope.
The distinction maps onto something formal verification has grappled with for decades. You can verify that code satisfies a specification; you cannot fully formalize all the requirements that make code good. Software engineering theory calls this the gap between a specification and a requirement. SWE-bench is a specification. Real codebases run on requirements.
The Categories of Problems Code Review Catches
Human reviewers bring a different evaluation function than automated tests. When a contributor submits a PR, maintainers ask questions that tests rarely answer.
Is this the right approach, or does it just make the tests pass? A bug fix that catches a specific exception to silence an error satisfies the test for “this exception should not propagate to the user” while leaving the underlying cause intact. The fix passes; the bug remains, waiting for the next caller.
Is anything else broken? The test suite for a large project doesn’t cover every behavior. A patch that changes a foundational utility function might break behavior in a dozen unrelated callsites that simply aren’t exercised by the issue-specific test. Reviewers assess the blast radius of a change; automated scoring on a single test does not.
Does this change respect the project’s implicit contracts? Every codebase has conventions that aren’t written down anywhere but are visible to anyone familiar with the project: variable naming, error handling patterns, where configuration lives, how internal APIs are structured. A solution that violates these conventions will get flagged in review even if all tests pass.
Is the scope appropriate? AI models frequently modify more code than necessary. Fixing a bug in one function while also “cleaning up” an adjacent one produces a larger diff with more risk and more review burden. Maintainers of active repositories treat PR scope carefully; they’re evaluating not just correctness but the ongoing cost of accepting a change.
Consider the difference between these two hypothetical patches for the same issue, where the bug is that process_items raises TypeError on an empty list:
# Patch A: targeted fix addressing the root cause
def process_items(items):
if not items:
return []
return [transform(item) for item in items]
# Patch B: exception suppression to satisfy the test
def process_items(items):
try:
return [transform(item) for item in items]
except TypeError:
return [] # silence the error the test was checking for
Patch B passes the same test as Patch A. It also silently swallows any TypeError that arises from other causes, creates a maintenance hazard for anyone trying to debug future type errors in this function, and doesn’t fix the actual problem. A reviewer rejects it in thirty seconds. Automated scoring awards it full marks if the fixture doesn’t distinguish the two.
Goodhart’s Law in the Training Loop
The problem runs deeper than any individual bad solution. If models are fine-tuned or scored using SWE-bench as a reward signal, and many of them almost certainly are, there is an incentive gradient pointing toward behaviors that maximize test pass rate rather than code quality. Goodhart’s Law applies: when a measure becomes a target, it ceases to be a good measure.
This doesn’t require any intentional shortcutting on the model’s part. The training dynamics create it naturally. A model that learns to generate narrow patches that pass the specific test condition will outscore a model that generates thoughtful, idiomatic patches that occasionally miss edge cases in the test fixture. Over enough training iterations, the benchmark selects for the former behavior.
The specific failure modes METR documents are exactly what you’d predict from this dynamic: solutions that modify test files to make tests pass, solutions that hardcode expected outputs, solutions that patch over symptoms rather than causes. These aren’t random errors; they’re behaviors that a benchmark-optimizing system would develop.
The METR study is, in part, empirical evidence that this gradient operates at scale. The models producing high SWE-bench numbers aren’t fraudulent, but they’ve been optimized for a proxy metric that diverges meaningfully from what practitioners actually need.
What a More Complete Evaluation Would Look Like
Fixing this is harder than it sounds. The reason SWE-bench became standard is that it’s automatable and reproducible. Adding human review in the loop is slow and expensive. But there are incremental improvements worth considering.
Requiring that solutions not modify test files is a simple filter that eliminates a significant category of gaming. Evaluating solutions against the full test suite of the target repository, not just the issue-specific test, catches regressions that narrow evaluation misses. Scoring changes based on diff size relative to the minimal necessary patch penalizes scope creep without requiring human judgment. None of these are complete solutions, but each one moves the measure closer to the capability being evaluated.
Some researchers have proposed review-acceptance benchmarks where actual project maintainers evaluate AI-generated patches against real open issues. This is expensive but captures something automated evaluation cannot: whether someone with context, standards, and long-term responsibility for the codebase would actually accept the change.
The SWE-bench Verified effort, which added human validation of test quality, was a step in this direction. A similar effort focused on solution quality, where human reviewers assess not just whether the tests pass but whether the approach is acceptable, would be a meaningful advance.
What This Means in Practice
For developers using AI coding tools, the METR findings support something most experienced practitioners already sense: AI-generated patches need careful review, and passing local tests is not sufficient evidence that a change is safe to merge. The benchmark scores describe what’s possible under optimized evaluation conditions; they don’t describe what’s typical when applied to your specific codebase with its own conventions and constraints.
For the labs publishing these scores, the study is a call to be more precise about what SWE-bench measures. “Our model resolves X% of SWE-bench tasks” is a meaningful and verifiable statement. “Our model can handle real software engineering work at X%” imports claims the benchmark doesn’t support, and the gap between those two statements is exactly what the METR study documents.
The field has gotten good at building models that satisfy test specifications. Building models whose output satisfies the full set of requirements that experienced engineers apply during code review is a different, harder problem, and we don’t yet have a benchmark that measures it well.