We're live on Product Hunt today Cooper&Wright - Sentry errors become merged GitHub PRs, automatically | Product Hunt
Cooper&Wright Automated bug fixes
Rails · Laravel · FastAPI · Flutter · Go · JavaScript · Rust in beta · Sentry-native
Automated bug fixes, seen through

We watch your Sentry & file the fix while you sleep. Then we stay on the pull request until it is green.

A per-issue fixer's unit of work is the Sentry issue, and its job ends at the pull request. Ours is the pull request that lands: we open the fix, watch its checks, fix what fails, round by round, and hand you a green PR to merge. Nothing merges without you.

See how it works
Ruby on Rails Laravel FastAPI Free while in beta Your merge, always
658 pull requests merged
224s median open to merge
76 CI fixes pushed

Measured over the last 30 days, across every repository Cooper&Wright watches. See all the numbers.

How it works

Three loops. & one GitHub App.

Install once, then turn each loop on per repository. Every loop has a place where it stops and hands the work back to you.

01

Sentry fixes

Watches
A Sentry project, mapped to a repository and a stack.
Does
Pulls the files in the trace, generates a fix with Claude, opens the pull request. Then it watches that PR's checks and fixes its own failures, round by round.
Stops
After three rounds it hands off, with the reason written on the row and an email to you. The merge is yours.
02

PR failure monitoring

Watches
The pull requests people open in a repository you flag, with or without a Sentry project.
Does
When a required check fails, the same fix rounds, pushed to that PR's own branch, with an email for each push.
Stops
Three rounds, then a hand-off. It never merges a person's PR.
03

Dependabot auto-merge

Watches
Dependabot's pull requests in a repository you flag.
Does
Fixes their CI, resolves their merge conflicts, and merges each one once every check is green, behind the merge gate you choose: every check, or the required ones.
Stops
A lockfile conflict goes to a person. These are the only merges Cooper ever makes, and only where you turned them on.
Before every push, in every loop, Cooper checks its own patch: it parses every file it touched with that language's own parser and refuses anything that carries a diff or conflict marker.
One incident

From the error & to your merge.

The arc of one incident, as its own page shows it: the error, the PR, a red check, Cooper's round, green, your merge, and the lesson it wrote. Representative data, invented for this page.

Timeline · representative
INC-A1B2C3D4 · acme/storefront
Reported 02:14

NoMethodError: undefined method 'full_name' for nil · app/models/user.rb:23

Fix generated 02:17

app/models/user.rb · self-check passed: ruby -c, no diff or conflict markers

PR opened 02:18

#482 · cooper-and-wright/fix-inc-a1b2c3d4

Checks failed · rspec 02:26

test/models/user_test.rb:41 · expected "Anonymous", got nil

Cooper attempting a fix (attempt 1 of 3) 02:31
Fix pushed 02:33

app/models/user.rb, test/models/user_test.rb · self-check passed: ruby -c on 2 files, no diff or conflict markers, 1 lesson pattern

Checks passed · rspec 02:41
Merged 09:05

by @maria, with one commit of hers on top of Cooper's

Lesson learned · wrong_file 09:06

Guard a missing profile in Profile#display_name, not at each caller.

Cooper's fix · 02:33
app/models/user.rb
def display_name
- profile.full_name
+ profile&.full_name || 'Anonymous'
end
What @maria shipped · 09:05
app/models/profile.rb
def full_name
- [first_name, last_name].join(' ')
+ [first_name, last_name].compact.join(' ').presence || 'Anonymous'
end

Cooper guarded the caller; she fixed the source. The difference is the lesson.

Every step above is a row on the incident's page. The times are representative.

Lessons

It learns & from you.

When a person fixes what Cooper could not, or closes its PR and ships something else, Cooper reads that diff against its own and writes a rule. The rule rides into its next fixes.

Lesson · acme/storefront

Guard a missing profile in Profile#display_name, not at each caller.

Cooper added a nil guard where the error was raised; the person changed the method that produced the nil, so every caller was fixed at once.

wrong_file overruled rails Stack-wide

A lesson with a pattern is also a gate: Cooper's next patch is checked against it before it is pushed.

Repository
Where every lesson starts. The rule is carried into each later fix in the repository that taught it.
Stack
A second repository on the same stack teaches the same rule, and it is promoted to every Rails, or Laravel, or FastAPI repository you run.
System
Taught again on another stack, it becomes a house rule for everything you run.
Mute
A rule you disagree with is never injected again, and never promoted. You can watch them accumulate on the Lessons tab.
Compared

How is this different from Sentry's Seer?

Seer finds the root cause of a Sentry issue and opens a fix PR for it, inside Sentry, one issue at a time, and it is good at it. Cooper&Wright starts where that ends. Its unit of work is the pull request, and it covers the pull requests Seer never sees: the ones people open, and Dependabot's.

Unit of work
A Sentry issue.
A pull request that lands.
Where it runs
Inside Sentry.
On GitHub, as an App, on the PR and its checks.
Ends at
A fix PR.
A green PR you merge, or a bounded hand-off with the reason.
Pull requests it sees
The ones it opens.
Those, the ones people open, and Dependabot's.
When you overrule it
The issue is closed.
It reads your fix against its own and keeps the rule.
Proof

We run it & on itself.

The repository Cooper&Wright lives in is watched by Cooper&Wright: its Sentry project is mapped, its pull requests are monitored, its Dependabot PRs are merged by it. The lessons it holds today came from its own mistakes. There are no customer quotes on this page yet, no logos, and no numbers we did not measure.

Ruby on Rails ≥ 7.0 Laravel ≥ 9.x FastAPI ≥ 0.100 Flutter & Dart · beta Go · beta JavaScript · beta Rust · beta

The stack is read from the repository's own manifests and shown beside your setting. If yours is on the list, sign in and let it watch a repository of yours.

Pricing

Free & in beta.

Every loop, every repository you connect, for as long as the beta runs. The tiers beneath are what it becomes.

Now
Free for beta testers.

No card. Sentry fixes, PR failure monitoring and Dependabot auto-merge, on as many repositories as you connect. Paid plans are what it becomes, and beta testers will hear from us before anything changes.

Planned pricing
Free
$0/mo

10 pull requests seen through a month · 1 repository · no card

Team
$149/mo

Unlimited pull requests · 10 repositories · team dashboard and shared lessons

FAQ

Common questions

Does it merge automatically?

Dependabot's PRs, yes, once every check is green, behind the merge gate you choose, and only in a repository where you turned auto-merge on. A Sentry fix or a PR a person opened waits for you unless you turn on its own auto-merge switch for that repository. Both are off by default.

What if the fix is wrong?

Close the PR, or push your own commit over it. Cooper learns from what you ship instead: it reads your fix against its own and distils a rule it carries into its next fixes. If its own PR's checks fail, it tries three rounds, then hands off with the reason on the row.

What does it read, and what does it write?

It starts from the files in the trace's in-app frames, then reads whatever it asks for through two read-only tools, read_file and list_directory, while it works. It writes only to its own PR branch, or to the branch of a PR you asked it to watch. The one exception is Dependabot: to make Dependabot rebase a conflicted PR, Cooper commits a comment to dependabot.yml on the default branch, marked [skip ci], at most once per PR.

Which stacks?

Rails, Laravel and FastAPI first. Flutter and Dart, Go, JavaScript and Rust are in beta. The stack is read from the repository's own manifests and shown beside your setting, so a wrong choice is caught rather than guessed at.

What happens after three failed rounds?

The PR is marked as needing attention, the reason is written on its row, and you get an email. Nothing is pushed again until you press Retry, which gives it a fresh budget of three.

Is self-hosted available?

Cloud only. Cooper&Wright is a GitHub App and a Sentry integration; there is nothing to run on your side.

The error is already in Sentry.

Start in beta & free.

Connect Sentry and GitHub in a couple of minutes. Free for beta testers, no card; the paid plans are what it becomes.