All jobs

Fix Errors in a Hono Deployment

Yes. Give an agent your Hono Worker's logged error; it checks deployed bindings against wrangler.toml, reproduces the request locally and opens a pull request.

Run this on RushIn a Project that has your repository.

What the agent does

The agent starts from the error text after the prompt: the exception message, the request path and query, and whatever stack the Workers log kept. In a Hono app like the durable-objects example in honojs/examples, the whole request path is durable-objects/src/index.ts. A createMiddleware factory reads ?name= from the query, answers with a usage message when it is missing, and otherwise calls c.env.COUNTERS.idFromName(name) and c.env.COUNTERS.get(id) to put a Durable Object stub on the context. Three routes, /, /increment and /decrement, call getCounterValue, increment and decrement on that stub, which src/counter.ts implements on a DurableObject subclass with this.ctx.storage.get('value') and put. The agent names which of those lines the error can come from before it changes anything.

Next it compares the deployment with the repository. durable-objects/wrangler.toml names the Worker durable-objects-counter, sets compatibility_date to 2024-05-01, binds COUNTERS to the class Counter, and declares a v1 migration with new_classes = ["Counter"]. Through the Cloudflare connection the agent reads the deployed Worker's bindings and Durable Object namespaces, so it can tell a code bug from drift: a binding renamed in the dashboard, a class migration that never ran, or a compatibility_date that differs from the file. A TypeError on c.env.COUNTERS being undefined is configuration; a RangeError from a counter that overflowed is code.

Then it reproduces the failing request in its sandbox. The example has wrangler ^3.50 and hono ^4.2.4 in durable-objects/package.json, the root package.json lists it as an npm workspace with packageManager npm@10.0.0, so the agent runs npm ci at the root, starts npm run dev in durable-objects/ (which is wrangler dev src/index.ts, with Durable Objects served by the local runtime) and sends the request from the log with curl until it sees the same error. A fix it cannot reproduce first is reported as a hypothesis, not shipped.

This example has no tests, so the agent adds what the repository's blog example already uses: vitest with @cloudflare/vitest-pool-workers and a vitest.config.ts that uses defineWorkersConfig and points at wrangler.toml, which gives the test a real COUNTERS namespace. The new src/index.test.ts sends the failing request through app.request() with the env from cloudflare:test and asserts the status and body the route should return. It fixes the middleware or the Counter class, runs npx vitest --run and npx tsc --noEmit, and only then pushes. It never runs wrangler deploy.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "The Worker deployed from durable-objects/ in this repository is throwing errors; the message, request path and stack from its Workers logs are pasted below. Use the Cloudflare connection to read the deployed Worker's bindings and Durable Object namespaces and compare them with durable-objects/wrangler.toml, including the COUNTERS binding and the v1 migration. Install with npm ci at the repository root, start wrangler dev in durable-objects/, and reproduce the failing request with curl. Fix the middleware in src/index.ts or the Counter class in src/counter.ts so the request succeeds or fails with a clear status instead of an uncaught exception. Add Vitest with @cloudflare/vitest-pool-workers, as the blog example in this repository uses, and a test that sends the same request through app.request with the env from cloudflare:test; run npx vitest --run and npx tsc --noEmit. 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, request path and stack trace here>",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ],
  "connections": [
    "cloudflare"
  ]
}
  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

A pull request on its own branch with the fix in durable-objects/src/index.ts or src/counter.ts, a new vitest.config.ts and src/index.test.ts, and the vitest and @cloudflare/vitest-pool-workers dev dependencies in durable-objects/package.json. The description quotes the error, says whether the cause was code or a binding that did not match wrangler.toml, shows the curl reproduction against wrangler dev and the test failing before and passing after, and lists the commands with their results.

When the cause is configuration, the pull request changes wrangler.toml to match what should be deployed, or explains the dashboard change a person needs to make, and the agent changes nothing in the account itself. The session transcript holds every Cloudflare call it made, each command with its output, and each file it read; GET /o/{org}/sessions/{id}/messages returns it.

A reviewer checks that the fix handles the request's actual input rather than catching everything in app.onError, that the test runs inside the Workers runtime and exercises the Durable Object rather than a mock, and that a wrangler.toml change still carries the v1 migration so existing objects keep their storage.

Run it on every Worker error alert

Point a Cloudflare notification or your log tool's alert at a handler on your 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. Group by message first so one noisy exception becomes one run, and use the error signature as the Idempotency-Key so a resent alert returns the run it already started.

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

The use case this job follows, with its automation and trigger: Fix a bug from an alert.

Why run it on Rush?

Debugging a Worker from its logs by hand means switching between the dashboard, the repository and a local wrangler dev, and it is easy to fix the code when the real problem was a binding. The agent reads both sides, the deployed bindings through your connection and wrangler.toml in the clone, and reproduces the request in a sandbox that has its own Node and Wrangler and touches nothing of yours.

The pull request carries its proof: the reproduced request, the failing-then-passing Workers test and a transcript of every command and Cloudflare call. Several Workers in a monorepo like this one can each get their own run at once, and nothing deploys until a person merges.

Frequently asked questions

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

The connection this page names is Cloudflare's Workers bindings server, which lists Workers and their KV, R2, D1 and Durable Object bindings. The error itself comes from you: paste it from the dashboard's logs or from wrangler tail, or have your alerting forward it, as the request shows.

Will it deploy the fix?

No. The prompt forbids wrangler deploy and any change in the account. The pull request is the result; you deploy from your usual pipeline after review.

How does the test reach a Durable Object?

@cloudflare/vitest-pool-workers runs the test inside the Workers runtime with the bindings from wrangler.toml, so env.COUNTERS in the test is a real namespace backed by local storage. That is the setup the repository's blog example already uses with defineWorkersConfig.

Does it work for the other examples in this repository?

Yes, for any workspace with a Wrangler config: basic, env-vars, jsx-ssr, serve-static and stytch-auth each have one. Name the directory in the prompt; the agent reads that example's wrangler file and bindings instead.