driftfix
Dependabot bumps it. CI breaks. driftfix fixes the code.
Dependency bots open the upgrade PR, then leave you to fix whatever broke. driftfix finishes the job: it reads the failing tests, has Claude adapt your code to the new version, reruns your tests itself, and pushes the fix onto the same PR. If it can't get to green, it comments what it tried and commits nothing.
Dependabot PR (openai 0.28 → 1.x)
→ tests fail
→ Claude reads the failure + changelog, edits your code
→ driftfix reruns your tests
✅ green → fix committed to the PR, with an explanation
❌ red → comment only, nothing committed
See it on a real Dependabot PR: driftfix-playground#1.
Benchmark
Real breaking upgrades. Each case is a small app whose tests pass on the old version and fail on the new one. Most include a trap beyond renames: a silent behavior change, a security footgun, or a multi-file refactor.
| Package | Upgrade | Fixed | Cost | Diff |
|---|---|---|---|---|
| httpx | 0.27.2 → 0.28.1 | ✅ | $0.12 | 1 file changed, 4 insertions(+), 1 deletion(-) |
| numpy | 1.26.4 → 2.5.3 | ✅ | $0.14 | 1 file changed, 5 insertions(+), 5 deletions(-) |
| openai | 0.28.1 → 3.24.0 | ✅ | $0.29 | 1 file changed, 4 insertions(+), 3 deletions(-) |
| pydantic | 1.10.21 → 2.13.5 | ✅ | $0.20 | 1 file changed, 11 insertions(+), 11 deletions(-) |
| sqlalchemy | 1.4.54 → 2.1.3 | ✅ | $0.19 | 1 file changed, 7 insertions(+), 4 deletions(-) |
| pydantic (6-file app, shared base model) | 1.10.21 → 2.13.5 | ✅ | $0.51 | 4 files changed, 47 insertions(+), 29 deletions(-) |
pydantic (BaseSettings moved to new package) |
1.10.21 → 2.13.5 | ✅ | $0.22 | 2 files changed, 8 insertions(+), 5 deletions(-) |
| pandas | 1.5.3 → 2.3.3 | ✅ | $0.19 | 1 file changed, 5 insertions(+), 5 deletions(-) |
| django | 3.2.25 → 5.2.17 | ✅ | $0.20 | 1 file changed, 7 insertions(+), 8 deletions(-) |
| flask | 2.2.5 → 3.1.3 | ✅ | $0.22 | 1 file changed, 6 insertions(+), 12 deletions(-) |
| pillow | 9.5.0 → 12.3.0 | ✅ | $0.13 | 1 file changed, 3 insertions(+), 2 deletions(-) |
| pyyaml | 5.4.1 → 6.0.3 | ✅ | $0.18 | 1 file changed, 2 insertions(+), 2 deletions(-) |
12/12 fixed, $2.59 total ($0.12–$0.51 per fix).
Every fix was verified by rerunning the tests, and no test was edited.
Reproduce with python bench/run.py (needs an API key), or validate the cases
for free with python bench/run.py --check.
Found an upgrade it can't fix? That's the most useful contribution: see
CONTRIBUTING.md.
Quick start: GitHub Action
-
Add
.github/workflows/driftfix.yml:name: driftfix on: pull_request permissions: { contents: write, pull-requests: write } jobs: fix: if: github.actor == 'dependabot[bot]' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: { ref: "${{ github.head_ref }}" } - uses: Gthejesraj/driftfix@v0 with: anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} setup: pip install -r requirements.txt # however you install deps test: pytest -q # however you run tests
-
Add
ANTHROPIC_API_KEYunder Settings → Secrets and variables → Dependabot. Workflows triggered by Dependabot can't read your normal Actions secrets.
That's it. The next Dependabot PR that breaks your tests gets a fix commit.
| Input | Default | |
|---|---|---|
anthropic-api-key |
required | |
setup |
pip install -r requirements.txt |
command that installs dependencies |
test |
pytest -q |
any command; exit code 0 = green |
package |
from Dependabot | set it for non-Dependabot PRs |
model |
claude-opus-5 |
|
budget |
5 |
max USD per run |
Quick start: CLI
pip install driftfix
export ANTHROPIC_API_KEY=sk-ant-...
# you upgraded a dependency and your tests fail:
driftfix fix --package openai --from 0.28 --to 1.40 --test "pytest -q"
Flags: --test, --model, --budget (USD, default 5), --max-turns
(default 50), --timeout (test timeout, seconds), --summary FILE (write the
markdown report), --repo PATH.
Exit codes: 0 fixed or nothing to fix, 1 not fixed, 2 dirty working tree.
Guardrails
- Your tests decide. driftfix reruns them after the agent finishes. The agent saying it's done doesn't count.
- No pinning back. Changing the upgraded package's requirement or editing
lock files is rejected. Adding a package the upgrade split out (like
pydantic-settings) is allowed. - No deleting or skipping tests. The agent is told not to, and every test change shows up in the diff you review.
- Reviewable. It needs a clean git tree, so every change is a diff, and it never merges.
- Bounded. Spend cap per run, and the cost is printed in every report.
See SECURITY.md for the threat model. The short version: the agent can run commands inside the checkout, so run it in CI or a throwaway clone.
FAQ
What does it cost? $0.12–0.51 per fix in the benchmark, billed to your Anthropic API key. When tests already pass, Claude isn't called at all.
Does my code leave my machine? Yes. The relevant files and test output are sent to the Anthropic API.
Which languages? Python is what's benchmarked. The Action takes any
setup and test command, so npm projects should work, but that's untested.
Reports are welcome.
Renovate instead of Dependabot? Use the CLI or set the package input.
Native Renovate support is on the roadmap.
Why doesn't CI rerun after the fix commit? GitHub doesn't trigger
workflows from commits pushed with the default GITHUB_TOKEN. Pass a personal
access token or GitHub App token to actions/checkout if you want that.
Mocked tests? driftfix can only catch what your tests catch. A test that mocks the library can pass while the real call is broken.
Roadmap
- More benchmark cases (langchain, Django REST framework), larger real repos
- npm and Renovate support
- Provider mode: packages publish migration notes that driftfix reads
Contributing
Bug reports, failed-fix reports and benchmark cases are all welcome. See CONTRIBUTING.md and the Code of Conduct.
License
Metadata
Release files for driftfix 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| driftfix-0.2.0.tar.gz | 21.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| driftfix-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.9 kB
Release files / driftfix-0.2.0.tar.gz
| Download URL | driftfix-0.2.0.tar.gz |
|---|---|
| Size | 21.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a340cb0d61dd95419c15cf997341f31e372fd9cc0f143ceb41b3efd31d41235c
|
|
BLAKE2b-256 checksum How to use checksums |
1768a5b2c225e02473b0eda91cd4e9fdeb1f748e8c14daf8343e813585abe152
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / driftfix-0.2.0-py3-none-any.whl
| Download URL | driftfix-0.2.0-py3-none-any.whl |
|---|---|
| Size | 8.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ced98d54f5a156fb0be3af52bcaad4832a53d01d199e05d7180ce0d36941d4f8
|
|
BLAKE2b-256 checksum How to use checksums |
bf518a47db51faa0ec7c4ad058ec5ae53a2339d48c73d4525a042a910e0bf2cd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log