Skip to content

GUIDES

SWE-bench Explained: What the Score Actually Measures

SWE-bench explained by running its own construction filter over a real repository. It produced zero task instances from 40 commits, and the reason is the benchmark's point.

SWE-bench explained in one sentence: it is 2,294 GitHub issues whose fixes shipped with a test, and a model scores by making that test pass. The fastest way to understand what the number means is not to read a leaderboard — it is to run the benchmark's own construction filter over a repository you know. We did that here, on the repository this site is built from, and it produced zero task instances from 40 commits. This article covers how instances are built, which fields decide a score, and what the filter selects for.

Key takeaways

  • SWE-bench instances survive a three-stage filter that keeps roughly 2.5% of the pull requests it sees: 2,294 instances from about 90,000 pull requests across 12 Python repositories.
  • A pull request qualifies only if it both resolves an issue and modifies test files. No test, no instance — that criterion is doing most of the selection.
  • Six of the twelve instance fields are unavailable in our repository, and all three that decide the score are among them. Everything describing a change is easy; everything establishing it was correct is not.
  • SWE-bench Verified is a 500-instance human-checked subset, created because original instances could be underspecified or graded by tests that fail a valid fix.
  • A score is evidence about a model plus a scaffold plus a task set, and only the first is something you can buy.

The short answer

SWE-bench measures whether a model can make a specific failing test pass, on a repository whose maintainers write tests alongside fixes. That is a real and hard capability. It is also narrower than "can this model do software engineering," and the gap between those two sentences is where most quoted scores get misused.

If you are choosing a tool rather than studying the benchmark, the best AI coding assistants comparison is the pillar this sits under, and best AI model for coding prices the current lineup on one measured turn.

What SWE-bench actually is

SWE-bench was introduced in SWE-bench: Can Language Models Resolve Real-World GitHub Issues? by Jimenez, Yang, Wettig, Yao, Pei, Press and Narasimhan, published at ICLR 2024. The abstract describes it as "an evaluation framework consisting of 2,294 software engineering problems drawn from real GitHub issues and corresponding pull requests across 12 popular Python repositories."

The task given to a model is deliberately unlike code generation. It receives a codebase at a specific commit and the text of an issue, and it must produce a patch. Nothing tells it which file to edit, and resolving an issue "frequently requires understanding and coordinating changes across multiple functions, classes, and even files simultaneously."

The scale of the challenge at publication is worth remembering when reading a modern score: the best-performing model in the paper, Claude 2, resolved 1.96% of instances. Published figures today are far higher. Some of that movement is model capability and some of it is scaffolding — the agent loop, the tools, the retrieval — and the benchmark does not separate the two for you.

The twelve repositories are all mature, well-tested Python projects, and their pull request counts are published in the paper:

RepositoryPRs scrapedRepositoryPRs scraped
django16,914scikit-learn15,159
matplotlib16,545sympy11,928
astropy9,469pytest5,147
sphinx4,931pylint3,848
xarray3,416flask2,434
requests2,344seaborn1,004

That selection is not incidental. The authors prioritised repositories with strong documentation and testing practices, because the construction pipeline cannot work without them.

How a task instance is built

Three stages, applied in order:

  • Stage I — scrape. Collect pull requests from the 12 repositories, "producing about ∼90,000 PRs in total."
  • Stage II — attribute filter. Keep pull requests that "(1) resolve a GitHub issue and (2) make changes to the test files of the repository, which indicates that the user likely contributed tests to check whether the issue has been resolved."
  • Stage III — execution filter. Apply the pull request's test changes, run the suite before and after the code changes, and "filter out task instances without at least one test where its status changes from a fail to pass," along with anything producing installation or runtime errors.

Roughly 90,000 in, 2,294 out. A survival rate near 2.5%, and the second stage is where most of the loss happens.

That second criterion is the one to hold on to. A pull request that fixes a real bug, is reviewed, merged and shipped, but does not add a test, is not eligible. Not because it is bad work — because there is no way to grade it automatically.

Running the filter on a repository we know

Reading the criteria is one thing. Applying them is faster. The committed check implements the same three stages against this repository's git history, using commits in place of pull requests, because this repository has none.

Terminal
npm run check:swebench
Output, 2026-08-17
Stage I — scrape

  Changes in history                    40

Stage II — attribute filter  (both criteria required)

  Mentions a #number                    1
  Resolves a GitHub issue               0
  Modifies the repository's test files  0
  Both                                  0

Stage III — execution filter  (at least one fail-to-pass test)

  Test command in package.json          none
  Test files tracked by git             0
  Can observe a test flip fail to pass  no

Task instances produced

  From this repository                  0 of 40  (0.00%)
  From the paper's 12 repositories      2,294 of ~90,000  (2.55%)

Zero, and the run never reaches the interesting stage. This repository has no test files and no test script, so the execution filter has nothing to execute — the attribute filter has already emptied the set.

Required disclosure: the first version of this script got the answer wrong, and the way it was wrong is instructive. It matched issue references with a bare #\d+ regex, which found one commit — Add articles #45, #48, #49 — Road 1 batch three — where the numbers are roadmap entry IDs and no GitHub issue exists. On that reading the script reported a fetchable problem_statement, for a problem statement that cannot be fetched. The fix was to match GitHub's closing keywords (fixes #12), which are what actually associate a merged change with an issue:

Output, 2026-08-17
  The first two rows differ, and the gap is the reason the second one exists.
  "Add articles #45, #48, #49 — Road 1 batch three"
  mentions a #number that is a roadmap entry, not a GitHub issue.

A five-minute bug in a small script, on a repository whose entire history one person wrote. Scale that across 90,000 pull requests from twelve projects and you have an argument for the human annotation pass covered below.

The twelve fields, and which ones decide the score

A SWE-bench Verified instance carries twelve fields, documented on the dataset card. Splitting them by what they do is more useful than listing them, because they are not equally hard to produce:

Output, 2026-08-17
  FIELD                       SUPPLIED   SCORING   FROM
  instance_id                 yes        —         MuhammadKashif10__devventa-<n>
  repo                        yes        —         MuhammadKashif10/devventa
  base_commit                 yes        —         the change's parent
  patch                       yes        —         non-test half of the diff
  created_at                  yes        —         2026-08-15T06:24:21+05:00
  environment_setup_commit    yes        —         any commit hash qualifies
  problem_statement           no         —         issue title and body
  hints_text                  no         —         issue comments before the fix
  version                     no         —         install version for evaluation
  test_patch                  no         yes       test-file half of the diff
  FAIL_TO_PASS                no         yes       tests the change makes pass
  PASS_TO_PASS                no         yes       tests that must not regress

  6 of 12 fields, and 0 of the 3 the harness reads to decide whether a
  submission resolved anything.

Every field describing the change is available. Every field establishing that the change was correct is missing. That split is the article in one table.

The three scoring fields work together. test_patch is the test-file half of the original pull request, applied to the repository before a submission is graded — so the model is evaluated against tests it never saw. FAIL_TO_PASS lists the tests the original fix made pass, and a submission must make them pass too. PASS_TO_PASS lists tests that passed before and after, so a submission cannot score by breaking the rest of the suite. An instance resolves only when both lists are satisfied.

This is a genuinely good grading design — it is objective, it is cheap to run, and it cannot be gamed by a plausible-looking diff. It also means the benchmark is structurally unable to contain a single instance from a project like this one.

SWE-bench Verified, and why it exists

SWE-bench Verified is described by the project as "500 instances from SWE-bench, created in collaboration with OpenAI," where "human annotators reviewed each instance to ensure the problem descriptions are clear, the test patches are correct, and the tasks are solvable given the available information."

Read that list of three checks against the pipeline above and the motivation is plain. Automated construction can produce an instance whose problem_statement does not contain enough information to identify the fix, or whose FAIL_TO_PASS tests assert implementation details specific to how the original author solved it — failing a correct alternative solution. Neither flaw is visible to the filter, because the filter only checks that a test flipped.

A caveat about the numbers usually quoted here. The annotation statistics that circulate — the share of samples flagged for underspecified problem statements, the share flagged for unfair tests — come from OpenAI's announcement post, which returned HTTP 403 to our fetch on 2026-08-17. We are not quoting figures we could not read at source. The three qualitative criteria above are from swebench.com and are quoted directly.

The practical consequence is one you can act on: a score on the original SWE-bench and a score on SWE-bench Verified are different measurements, and the same system scores higher on Verified because a chunk of unwinnable instances is gone. Comparing across the two is a category error, and a leaderboard screenshot that does not name the variant is not usable.

What a score is evidence of

Strip out everything the benchmark does not establish and this is what survives:

QuestionAnswerBasis
Can the system fix a described bugYes, at the measured rateFail-to-pass tests, objectively graded
Was it the model or the scaffoldNot separatedA submission is a whole system
Will it work on an untested repoNot measuredEvery instance ships a test patch
Does it hold outside PythonNot by this benchmark12 Python repositories

The second row is the one that matters commercially. A published score belongs to a configuration — a model, an agent loop, a tool set, a retrieval strategy, a budget. You can license the model. The rest of that configuration is somebody's product, and swapping your own harness in changes the number. It is the same reason this site's Claude vs GPT for coding measurement found 2 of 32,005 input tokens were typed by a person: in an agent, the scaffold is most of the request.

The fourth row is narrowing rather than fixed — the project now publishes Multilingual and Multimodal variants alongside the original — but a bare "SWE-bench" number still means the Python set. We later counted that set row by row: of the 623 files the Verified gold patches change, 622 are .py, and 231 of the 500 instances come from Django alone. The full distribution is in what the evidence behind a Python model choice is made of.

What we are not claiming

This article does not report a leaderboard position for any model, and the omission is deliberate. Scores move between releases, they are reported against different variants, and this site has no way to verify a submission that it did not run.

Two limits on the measurement it does report. Commits are not pull requests — this repository has none, so the filter was applied to the closest available unit, and a project with a real pull request workflow would give the attribute filter more to chew on. And the test-file pattern is a heuristic: it matches the conventions of six ecosystems, generously, so that a zero cannot be blamed on looking in the wrong place. Both choices are visible in the script rather than described here.

Common mistakes reading a benchmark score

  • Treating a score as a model property. It belongs to a model plus a scaffold plus a task set; two of those three are not for sale.
  • Comparing across variants. SWE-bench and SWE-bench Verified are different measurements, and Verified reads higher for structural reasons.
  • Comparing across years. A 2024 figure and a 2026 figure differ by scaffold as well as by model.
  • Generalising to untested code. Every instance ships a test patch. That is the population the score describes.
  • Assuming a hard benchmark is a representative one. SWE-bench is hard and narrow; those are independent properties.

Conclusion

Treat a SWE-bench number as a floor on a system's ability to fix a described bug in a well-tested Python project, name the variant whenever you quote it, and never read it as a forecast for your own repository until you have checked that your repository looks like the ones it is built from. The cheapest way to check is to run the filter: npm run check:swebench implements all three stages, and on the repository this article was written in it returned zero instances from forty commits — which told us more about our own testing practice than about any model.

Frequently asked questions

What is SWE-bench?
SWE-bench is an evaluation framework of 2,294 software engineering problems drawn from real GitHub issues and their pull requests across 12 popular Python repositories, introduced by Jimenez et al. at ICLR 2024. A model is given a codebase and an issue description and must edit the codebase so that tests which previously failed now pass.
How are SWE-bench task instances created?
Three stages. Pull requests are scraped from 12 Python repositories, roughly 90,000 in total. Attribute filtering keeps only pull requests that resolve a GitHub issue and modify the repository's test files. Execution filtering then keeps only those where at least one test changes status from fail to pass, discarding installation and runtime errors. 2,294 instances survive.
What is the difference between SWE-bench and SWE-bench Verified?
SWE-bench Verified is a 500-instance subset of the SWE-bench test set, created with OpenAI, where human annotators checked that each problem description is clear, the test patch is correct, and the task is solvable from the information available. It exists because a substantial share of original instances were underspecified or graded by tests that could fail a valid solution.
What do FAIL_TO_PASS and PASS_TO_PASS mean?
They are the two test lists that decide whether a submission counts as resolving an instance. FAIL_TO_PASS holds the tests the original pull request made pass, so a submission must make them pass too. PASS_TO_PASS holds tests that passed before and after, so a submission must not break them. Both come from the pull request's own test patch.
Does a high SWE-bench score mean a model will work on my codebase?
Only if your codebase looks like the ones the benchmark is built from. Every instance comes from a pull request that both resolved an issue and shipped a test flipping fail to pass. Running that filter over the repository this article was written in produced zero instances from 40 commits, because it has no test suite — so a score says nothing measurable about work like it.

Muhammad Kashif

Founder and editor of Devventa, covering AI coding assistants, Next.js and the modern AI development stack.