What the agent does
The agent reads the issue after the prompt and pulls its latest event through the Sentry connection: the exception class and message, the transaction, the breadcrumbs with the SQL and HTTP calls before the failure, the release tag and the in-app frames. For a Django app the transaction is already a function name when the SDK is set up that way, which is the case in django/djangoproject.com: djangoproject/settings/prod.py calls sentry_sdk.init with DjangoIntegration(transaction_style="function_name") and RedisIntegration(), with a 0.1 traces sample rate, when a sentry_dsn is present in the secrets file and DEBUG is off.
That site is a Django 6.1.1 project on Python 3.12 with Postgres 17, django-hosts 7.0 and several apps: accounts, aggregator, blog, checklists, contact, dashboard, docs, foundation, fundraising, legacy, members, releases, svntogit and tracdb. djangoproject/hosts.py routes the www, docs and dashboard hostnames to three URL confs, so a transaction such as docs.views.document or fundraising.views.configure_checkout_session tells the agent both the app and the hostname. It opens the view the frame names, its form or model, and the template if the exception came from rendering.
The common shapes are specific to each app. docs/views.py serves document, search_results and search_suggestions for a language and version, so a DoesNotExist or a KeyError on a release that has no built docs lands there. fundraising/views.py talks to Stripe 13.2 in configure_checkout_session, receive_webhook and WebhookHandler, so an unexpected event shape or a missing DjangoHero raises there. blog/views.py is a set of date-based generic views, and releases/views.py has roadmap and redirect with version parsing. The agent reads the breadcrumbs for the URL and query parameters and builds the request that reproduces the frame.
Tests live beside each app, as tests.py or a tests/ package: docs/tests/test_views.py, fundraising/tests/test_views.py, blog/tests.py, releases/tests.py. The agent adds one test method to the matching module, using the Django test client against the hostname django-hosts expects, confirms it fails with the Sentry exception, fixes the view or model, and runs python -m manage test <app> the way Makefile's test target does, after creating the two Postgres databases and the conf/secrets.json the tests.yml workflow shows. It then opens a pull request that links the Sentry issue and quotes the frames and the test output. If it cannot reproduce the error, it stops at needs_review and says what it tried.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "A Sentry issue for this Django repository is attached below. Read its latest event through the Sentry connection: the exception, the transaction (a view function name), the breadcrumbs with the request URL, query string and SQL, the release tag and the in-app frames. Open the view the frame names and its form, model or template; the apps are routed by djangoproject/hosts.py, so use the www, docs or dashboard URL conf the transaction belongs to. Add one test method to that app's tests.py or tests/test_views.py that performs the same request with the test client and confirm it fails with the same exception. Fix the cause rather than catching the exception, run python -m manage test for that app with the two Postgres databases and the conf/secrets.json the tests workflow sets up, and open a pull request that links the Sentry issue, quotes the frames and the failing test output and explains the cause. Stop at needs_review if you cannot reproduce it.\n\nSentry issue:\n{issue}",
"connections": [
"sentry"
],
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- 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
What comes back is a pull request that changes one view, form or model in a single app and adds one test method beside it, for example a case in docs/tests/test_views.py that requests a document for a version with no built docs and now gets a 404 instead of a 500. The description links the Sentry issue, names the transaction and the frame, states the cause, and shows the test failing before and passing after, with the manage test summary for that app.
The reviewer checks that the test goes through the URL conf for the right hostname, that the fix handles the input the breadcrumbs showed rather than wrapping the view in a broad except, and that a 404 or a redirect is the right answer for a user rather than a silent empty page. For the fundraising app, a change in WebhookHandler should keep Stripe signature checking as it was.
A run that ends needs_review has no pull request; its result explains what the agent tried, for example that the query parameters in the breadcrumbs no longer reach the view after a recent URL change, so a person can decide whether the issue is already resolved.
Run it on every Sentry issue alert
Create an alert rule in the Sentry project for new issues with a webhook action pointed at a handler on your server. The handler sends this request with the issue JSON after the prompt and the Sentry issue id as Idempotency-Key, so a retried delivery returns the run already started. Sentry cannot send the Authorization: Bearer header a Rush webhook trigger requires, so the handler is what forwards, either to POST /o/{org}/sessions or to an automation's trigger in the Project.
Give the API key a webhook URL to receive run.completed or run.failed with the session_url, and let the handler comment the pull request link on the Sentry issue. Noisy issues that fire many times an hour should be deduplicated by issue id in the handler, or capped with the automation's max_runs_per_hour.
The use case this job follows, with its automation and trigger: Fix a bug from an alert.
Why run it on Rush?
A multi-app Django site with two databases, a Trac import and host-based routing takes real time to stand up locally, and a Sentry error from the fundraising app is not something a volunteer wants to reproduce against Stripe by hand. The agent builds that environment in its own sandbox from the same steps the CI workflow uses, and the maintainer sees a pull request with a failing test instead of a stack trace.
Each pull request carries its evidence: the event that was read, the test that failed with the same exception, the manage test output after the fix. Several issues can be several sessions at once, each isolated, and a run that cannot reproduce its issue says so rather than guessing.
Frequently asked questions
How does the agent know which app and hostname an error belongs to?
From the transaction, which DjangoIntegration(transaction_style="function_name") sets to the view's dotted path, and from djangoproject/hosts.py, which maps www, docs and dashboard to their URL confs. The test then sets the matching HTTP_HOST so django-hosts resolves the right routes.
Does the sandbox need the Trac database?
For tracdb and the dashboard, yes, and the tests.yml workflow shows how: a second Postgres database loaded from tracdb/trac.sql. For an error in docs, blog or fundraising the agent still creates both databases so the test settings load, but the test itself touches only the main one.
Will it fix the error by adding a try/except around the view?
No. The prompt asks for the cause. A DoesNotExist for a missing release should become a get_object_or_404, a bad query parameter should be validated in the form, and a Stripe event with an unexpected shape should be handled in WebhookHandler for that event type.
Which test runner and command does it use?
Django's own, through python -m manage test <app>, which is what the Makefile test target wraps with coverage. It installs requirements/tests.txt, which pins Django 6.1.1, psycopg 3.3.4, requests-mock and time-machine, and runs only the app the issue belongs to.
What if the issue is from a release that no longer matches main?
The agent compares the event's release tag with the current code. If the frame is already gone, the pull request still adds the test for the current behavior, says the issue is likely resolved, and leaves resolving it in Sentry to a person.