What the agent does
A browser error in Sentry comes with the exception, the page URL, the release, the user's browser and the frames of the bundled JavaScript, mapped back to source when the project uploads source maps. The agent reads the alert payload after the prompt, fetches the issue and its latest event through the Sentry connection, and keeps the frames, the breadcrumbs that show which actions preceded the error, and the tags. Then it opens its clone and finds the source files the frames name.
In a React app like excalidraw/excalidraw the Sentry setup is in excalidraw-app/sentry.ts: @sentry/browser 9.0.1 initialised with a DSN only on the production and staging hostnames, release set from VITE_APP_GIT_SHA, an ignoreErrors list for Safari, IndexedDB and storage quota noise, captureConsoleIntegration for console.error, and a beforeSend that builds a synthetic ConsoleError exception from callsites when there is no real one. .github/workflows/sentry-production.yml creates a release and uploads source maps from build/static/js with sentry-cli, so frames in production events already point at packages/excalidraw. The export and clipboard code the alert names is there: exportCanvas in packages/excalidraw/data/index.ts throws on an empty canvas, branches on svg, clipboard-svg, png and clipboard, calls canvasToBlob and encodePngMetadata, and maps a CANVAS_POSSIBLY_TOO_BIG error and a Firefox TypeError to translated messages; packages/excalidraw/clipboard.ts holds parseClipboard, parseDataTransferEvent, readSystemClipboard, copyToClipboard, copyBlobToClipboardAsPng and serializeAsClipboardJSON; packages/excalidraw/data/blob.ts has loadFromBlob, loadSceneOrLibraryFromBlob, canvasToBlob and resizeImageFile. The monorepo is yarn 1.22.22 workspaces with excalidraw-app, packages/* and examples/*.
The tests already cover this area, so the new one goes beside them. packages/excalidraw/clipboard.test.ts drives parseClipboard with createPasteEvent and API.createElement, packages/excalidraw/tests/export.test.tsx renders <Excalidraw /> and loads fixtures/smiley.png through API.loadFile, and tests/helpers/api.ts builds elements and files. vitest.config.mts aliases @excalidraw/* to the package sources, runs in jsdom with vitest-canvas-mock from setupTests.ts, and the root yarn test:app is vitest. The agent writes a test that feeds the function the input the breadcrumbs imply, such as a paste with an unexpected MIME type or an export with a frame that has no elements, runs yarn vitest run <file> and keeps the failing output as the reproduction.
Then it fixes the cause, reruns the test until it passes and runs yarn test:typecheck, yarn test:code, the ESLint pass with zero warnings allowed, and yarn test:app, the three checks behind yarn test:all; CI's test.yml runs yarn test:app on Node 20 and test-coverage-pr.yml enforces the coverage thresholds in vitest.config.mts. It does not add the error to ignoreErrors in sentry.ts to silence it, and where a clipboard call is expected to fail in some browsers it keeps the translated message the user already sees and fixes the path that threw something else.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "A Sentry alert fired for this React app; its payload follows this prompt. Use the Sentry connection to read the issue, its latest event, the breadcrumbs and the in-app stack frames. Match the frames to the source under packages/excalidraw, starting with exportCanvas in data/index.ts, clipboard.ts and data/blob.ts. Add a Vitest test beside the existing ones, clipboard.test.ts or tests/export.test.tsx, using the helpers in tests/helpers/api.ts, that reproduces the error. Fix the code until `yarn vitest run` passes for that file, then run `yarn test:typecheck`, `yarn test:code` and `yarn test:app`. Open a pull request that links the Sentry issue, quotes the frames and the failing test output, and explains the cause. Do not add the error to ignoreErrors in excalidraw-app/sentry.ts. Change nothing unrelated to this error.\n\nAlert payload:\n{payload}",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
],
"connections": [
"sentry"
]
}- 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.
- 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.
- 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
You get a pull request that changes one source file under packages/excalidraw and adds one test beside the existing ones. The description links the Sentry issue, quotes the exception and the frames it mapped, names the breadcrumb that led to the input it reproduced, shows the test failing before and passing after, and lists the typecheck, lint and test commands with their summary lines.
The session transcript keeps every Sentry read, every yarn command with its full output, and every file the agent opened, so a reviewer can confirm the zero-warnings lint actually ran. The run.completed webhook carries the agent's final message as data.result and a session_url to read the rest.
Before merging, a reviewer checks that the test's input matches the breadcrumbs rather than a simpler case, that a change in exportCanvas keeps the translated messages users see on Firefox and on oversized canvases, and that nothing in sentry.ts changed. A follow-up message to the same session changes the approach on the same branch.
Run it on every Sentry issue alert
Create an alert rule in the Sentry project with a webhook action and aim it at a handler on your server. The handler sends this request with the alert's JSON after the prompt and the issue id as Idempotency-Key, so Sentry's retries map to one run. Each new issue gets its own sandbox and its own pull request.
Set a webhook URL on the API key and Rush POSTs run.completed with session_url when the pull request is ready, so the handler can comment the link on the issue. Or have that handler call a webhook trigger on an automation in the Project with this prompt: it forwards the alert's JSON as the body with the trigger's secret as Authorization: Bearer, because Sentry signs its own webhooks and cannot send that header. The body becomes the event text after the prompt, and max_runs_per_hour caps an issue that keeps firing.
The use case this job follows, with its automation and trigger: Fix a bug from an alert.
Why run it on Rush?
A browser error that only some users hit is slow to chase by hand: you read the mapped frames, guess the clipboard payload or the scene that triggered it, and then install a large monorepo to try it. In a Rush sandbox the agent reads the event, builds the input from the repository's own test helpers and runs the project's typecheck, lint and tests on its own disk, with your checkout untouched.
The result is reviewable rather than trusted: a failing test, the same test passing and a transcript of each command. Issues run in parallel in separate clones, up to the key's max_concurrent limit, so a release that broke export on one browser and paste on another gets two small pull requests at once.
Frequently asked questions
Do I need source maps in Sentry for this to work?
They make it precise. This repository already uploads them in sentry-production.yml with sentry-cli sourcemaps upload, so frames name packages/excalidraw files. Without maps the agent works from function names and the error message and says in the pull request which frames it could not place.
Which runner and package manager does it use?
Vitest, which yarn test:app runs with the aliases and jsdom environment from vitest.config.mts, and yarn 1.22.22 from packageManager in the root package.json. The lockfile stays as it is because no dependency is added.
Can it reproduce an error that only happens in Safari or Firefox?
In jsdom it reproduces the code path, not the browser: the test feeds the input and the thrown error the breadcrumbs show, such as a missing ClipboardItem. The pull request says which part is browser-specific, and the sandbox browser can be used for a manual check in a follow-up.
Will it touch the ignoreErrors list?
No. The prompt forbids it, because adding a pattern there hides the error from Sentry without fixing it. If the agent concludes the error is noise of that kind, it says so in its final message and opens no pull request.