# Investigate Errors in a Cloudflare Worker

Yes. An agent reads your Worker's code, wrangler config and recent commits and writes an incident report ranking each error suspect with file:line evidence.

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

## What the agent does

The agent clones the repository into its own cloud sandbox and reads the Worker the incident names. In `to-do-list-kv-template` from cloudflare/templates, `wrangler.jsonc` sets `main` to `./server.ts`, `compatibility_date` `2025-10-08`, the `nodejs_compat` flag, `upload_source_maps: true`, `observability.enabled: true` and one KV namespace bound as `TO_DO_LIST`. `package.json` shows a Remix app on Workers: `@remix-run/cloudflare` `2.17.2`, `wrangler` `4.136.1`, and Vitest `3.2.7` with `@cloudflare/vitest-pool-workers` for the tests in `test/`.

Then it follows a request. `server.ts` wraps Remix's `createRequestHandler` in a `try`/`catch` that logs with `console.log` and answers a plain 500, so an exception thrown during a request becomes a 500 and not a Cloudflare error page; the agent notes that an error code like 1101 has to come from outside that handler and checks module scope and the `./build/server` import for it. The route `app/routes/$id.tsx` builds a `TodoManager` from `app/to-do-manager.ts` with the KV binding and `params.id`, and every intent (`create`, `toggle`, `delete`) first calls `list()`.

That is where CPU time goes. `list()` reads the whole list as one KV value with `kv.get(todosKey, "json")`, sorts it in memory, and each write serializes the whole array again with `JSON.stringify` and `kv.put`. The cost of every request grows with the size of one key, so a long list runs into the CPU limit while a short one never does, which fits an error rate that jumps for some users and not others. The agent also records that every `put` passes `expirationTtl: 300`, so a list disappears five minutes after its last write, and that `toggle` throws `Todo with id ${id} not found` when the id is gone, which an expired list makes likely.

Last it reads the 30 most recent commits for changes to these files, the compatibility date and the dependency versions, runs `npm test` in the sandbox to see whether the existing tests still pass, and writes for each suspect the check that confirms it in Workers Logs, which `observability.enabled` turns on: CPU time per invocation by route, the outcome field for exceeded CPU, and the size of the KV values involved. It changes no code and deploys nothing.

## Start it with one API call

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

```json
{
  "agent": "claude",
  "input": "Incident: after a deploy of to-do-list-kv-template, Cloudflare shows the Worker's error rate jumping from 0.1% to 7%, mostly exceeded CPU time and 1101 errors. Read wrangler.jsonc, server.ts, the routes, app/to-do-manager.ts and the last 30 commits, and run npm test. Find the most likely causes, and write incident.md with a timeline, each suspect with file and line evidence, which error each one would produce, and the Workers Logs query or check that would confirm or clear it. Change no code and deploy nothing.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

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 `incident.md` as an artifact on the session, with a download link the session read returns. It opens with a timeline from the deploy and the commits, then ranks the suspects. For this Worker that means the whole-list read, sort and rewrite in `TodoManager` for CPU time, the five-minute `expirationTtl` and the `toggle` throw for errors after a list expires, and anything at module scope that would throw before the `try` in `server.ts` for 1101s, each with the quoted line and the error it would produce.

Each suspect ends with the check that settles it in Workers Logs or the dashboard, and the report includes the `npm test` output from the sandbox. The session's transcript keeps every file read and every command run, so the evidence can be checked against its source.

Before acting, the engineer checks CPU time per invocation against list size in Workers Logs and decides on a fix, such as one KV key per item or a Durable Object for the list. A follow-up message to the same session can ask the agent to make that change with tests on a branch and open a pull request.

## Run it on every Worker deploy

Run it right after each deploy while it is still cheap to roll back. The step in your pipeline that runs `wrangler deploy` can send this request with the deploy's version and the commit range, and a report on what the deploy changed and what could fail is ready within the run.

Set a webhook URL on the API key and Rush POSTs `run.completed` when the turn finishes, with the `session_url`. Your handler reads `incident.md` from the session's artifacts and posts it beside the deploy notification.

## Why run it on Rush?

Worker incidents are often about limits rather than bugs: CPU time per request, the size of a KV value, an expiry nobody remembered. Finding them means reading the config, the handler and the storage code together and knowing which error each would produce. In a Rush sandbox the agent installs the project, runs its tests and reads it all on its own disk, and nothing reaches your Cloudflare account.

The report is cited line by line and each suspect has a check to settle it, with the transcript kept for review. When several Workers alert after a shared change, each one can get its own run at once, up to the key's concurrent run limit.

## Frequently asked questions

### Does the agent need my Cloudflare API token?

No. It reads the repository and runs the tests in the sandbox. If you want it to read your Workers and bindings directly, connect the Cloudflare MCP server and name it on the run.

### Will it deploy anything?

No. The prompt says to change no code and deploy nothing, and the agent never runs `wrangler deploy`. The result is a Markdown report.

### Can it run my Worker's tests?

Yes. The template's tests use Vitest with `@cloudflare/vitest-pool-workers`, which runs them in the Workers runtime locally, so `npm test` works in the sandbox without a Cloudflare account.

### Why does it care about the KV value size?

Because this Worker reads, sorts and rewrites the whole list on every request, so CPU time grows with one key's size. The report asks you to compare CPU time per invocation with list size to confirm it.
