# Fix Cloudflare Worker Errors From Its Logs

Yes. Give an agent the Worker's error, and it checks the bindings, reproduces the request with wrangler dev, and opens a PR with the fix and a Vitest test.

[Run this on Rush](https://cloud.getrush.ai/run/fix-cloudflare-worker-errors/cloudflare-workers/), in a Project that has your repository.

## What the agent does

The agent starts from the error you hand it and from the code that threw it. In a Worker built from Cloudflare's `d1-template`, the whole request path is `src/index.ts`: one `fetch` handler that runs `env.DB.prepare("SELECT * FROM comments LIMIT 3")`, calls `.all()` and passes the rows to `renderHtml` in `src/renderHtml.ts`. There is no `try`/`catch` around the query, so a missing table, a renamed column or an unbound `DB` surfaces as an uncaught exception and a 500 for every visitor. The agent reads the stack trace you paste, matches its frame to the line in `src/index.ts`, and writes down which of those failures it points at before touching anything.

Next it checks the deployed side against the repository. `wrangler.json` binds `DB` to `d1-template-database` with `compatibility_date` `2025-10-08` and `observability.enabled: true`. Through the Cloudflare connection, the agent lists the account's Workers and D1 databases and reads the deployed Worker's bindings, so it can tell a code bug from a configuration drift: a binding named `DB` in the file but something else in production, or a database whose schema never got `migrations/0001_create_comments_table.sql`. The template's `predeploy` script applies migrations with `wrangler d1 migrations apply DB --remote`, so a deploy that skipped that script is one of the first things it rules in or out.

Then it reproduces the failure locally in its sandbox. The `dev` script is `pnpm seedLocalD1 && wrangler dev`, while the template ships a `package-lock.json` and no `pnpm-lock.yaml`, so the agent installs with `npm ci`, runs `npx wrangler d1 migrations apply DB --local` itself, starts `wrangler dev` (wrangler 4.136.1 from `devDependencies`) and sends the failing request with `curl` until it sees the same error the logs showed. A fix that cannot be reproduced first is reported as a guess, not shipped as a fix.

The template has no tests, so the agent adds the setup Cloudflare uses in its sibling `d1-starter-sessions-api-template`: `vitest` with `@cloudflare/vitest-pool-workers` and a `vitest.config.mts` that points `cloudflareTest` at the Wrangler config. The new test sends the same request through the Workers runtime and asserts the status and body. It fixes the handler, runs `npx vitest run` and `npm run check` (`tsc && wrangler deploy --dry-run`), and only then pushes. It never runs `wrangler deploy`.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "The Worker deployed from d1-template in this repository is returning 500s. The error and stack trace from its Workers logs are pasted below. Use the Cloudflare connection to read the deployed Worker's bindings and its D1 database, and compare them with wrangler.json and migrations/. Install with the lockfile in the repository, apply the migrations locally, start wrangler dev and reproduce the failing request with curl. Fix the handler so the request succeeds, or fails with a clear status instead of an uncaught exception. Add Vitest with @cloudflare/vitest-pool-workers and a test that sends the same request, run the tests and npm run check, and open a pull request that quotes the error it fixes and says whether the cause was code or configuration. Do not run wrangler deploy or change anything in the Cloudflare account.\n\nError:\n<paste the error and stack trace here>",
  "resources": [
    {
      "url": "https://github.com/your-org/your-worker"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request against the Worker's repository. In a repository shaped like `d1-template` it changes `src/index.ts` (the handler, and error handling around the D1 call where that is the right fix), adds `vitest.config.mts` and a test file such as `test/index.spec.ts`, and adds `vitest`, `@cloudflare/vitest-pool-workers` and a `test` script to `package.json` and `package-lock.json`. When the cause was a missing migration or a binding that differs from `wrangler.json`, the description says so plainly and the code change is limited to what the repository can fix; the remote step is listed for a person to run.

The description quotes the error from the logs, shows the `curl` request that reproduced it under `wrangler dev`, and names the file and line it fixed. The session's trajectory keeps every command with its output: the local migration, the failing response, the passing test, the `wrangler deploy --dry-run` that checks the bundle builds. If the repository has CI, its checks run on the pull request as usual.

Before merging, a reviewer checks that the fix addresses the quoted error rather than hiding it behind a blanket catch, that the new test fails without the fix, and that any configuration change in `wrangler.json` matches the Worker in the account. Deploying stays your step, through whatever pipeline already deploys the Worker.

## Run it on every Worker error alert

Point a Cloudflare notification or your alerting tool's webhook at your own server, and on each new error signature have it send this request with the error text in `input` and the Worker's repository in `resources`. Each alert gets its own run in its own sandbox and its own pull request, so two unrelated errors do not end up in one branch. Group alerts by error message on your side first, or one noisy exception starts a run per occurrence.

Set a webhook URL on the API key and Rush POSTs `run.completed` or `run.failed` when the run's turn finishes, with the `session_url`, so your server can post the pull request link back to the alert. A key runs at most `max_concurrent` sessions at once (4 by default) and answers `429` past that, so queue alerts that arrive in a burst.

## Why run it on Rush?

Fixing a Worker from production errors on a laptop means tailing logs, matching a minified frame to source, running `wrangler dev` with a local D1 and juggling an account token that can deploy. On Rush the agent does that in its own sandbox with its own clone: it applies the migrations to a local database there, starts `wrangler dev`, and reproduces the request before changing a line. Your machine, your local D1 state and your Wrangler login are not involved.

The result shows its work. The pull request carries the quoted error, the reproducing request and a test that runs in the Workers runtime, and the trajectory keeps every command and its output, so a reviewer can see whether the fix was tested against the real failure. Separate errors become separate runs at once, each with a branch a person reviews before anything is deployed.

## Frequently asked questions

### Can the agent read my Worker's logs through the Cloudflare connection?

The Cloudflare server in Rush's catalog works with Workers and their bindings: KV, R2, D1 and Durable Objects. It does not read Workers logs, so paste the error and stack trace into the request. If you want the agent to pull logs itself, connect a Cloudflare observability MCP server as a custom server and name it in `connections`.

### Will it deploy the fix?

No. The request tells it not to run `wrangler deploy`, and it only runs `wrangler deploy --dry-run` to check the bundle. The change reaches production when you merge and deploy it the way you already do.

### How does the run get the Cloudflare connection?

Connect Cloudflare once with `POST /me/connections`, then add its id or name to `connections` in the request. A key run gets only the connections it names, so a request without it still fixes the code from the pasted error, but cannot check the deployed bindings.

### My Worker has no tests. What does the test run on?

It adds Vitest with `@cloudflare/vitest-pool-workers`, the same setup Cloudflare's own D1 sessions template uses, so the test runs the handler inside the Workers runtime with the D1 binding from your Wrangler config. The new dependencies and the `test` script are part of the pull request diff.
