# Turn Sentry Errors Into Fix Pull Requests for a VS Code Extension

Yes. From a Sentry alert the agent maps the frames to your extension's source, reproduces the error with a VS Code test under xvfb, fixes it and opens a PR.

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

## What the agent does

An error from a VS Code extension reaches Sentry from the extension host, and its frames name the compiled output, out/extension.js or a provider file beside it, rather than the TypeScript. The agent reads the issue and its latest event through the Sentry connection, takes the function names, the command id or the provider method in the frames, and maps them to src through the source maps that tsconfig.json emits with sourceMap set to true. It also reads the event's tags for the VS Code version and the extension version, because an API that moved between releases is a common cause.

In a repository like microsoft/vscode-extension-samples each sample is its own package: helloworld-test-cli-sample declares engines.vscode ^1.100.0, compiles with tsc -p ./ to out, runs tests with vscode-test from @vscode/test-cli ^0.0.8 over @vscode/test-electron, and configures the runner in .vscode-test.mjs with files set to out/test/**/*.test.js; its test suite in src/test/suite/extension.test.ts uses mocha's suite and test with assert. Most samples have only compile and lint scripts, and the root package.json offers compile-all and lint-all, which run each sample's script through .scripts/run-script.ts, while ci.yml runs only npm run validate to check that every folder is listed in .scripts/samples.ts and the README is current. So a sample like codelens-sample, whose CodelensProvider builds a regex over the whole document and reads the codelens-sample.enableCodeLens setting on every provideCodeLenses call, has no test of its own until the agent adds one.

The agent adds @vscode/test-cli, @vscode/test-electron, mocha and @types/mocha as dev dependencies of the failing sample where they are missing, copies the .vscode-test.mjs shape from the test-cli sample, and writes a test under src/test that activates the extension in a real VS Code instance and drives the path the frames name: it opens a document with the content the event implies and asks for code lenses, runs the registered command, or changes the configuration that triggers onDidChangeConfiguration. It runs npm run compile and then xvfb-run -a npm test, because vscode-test downloads VS Code and needs a display, and keeps the failing output, which shows the same error as the Sentry event.

Then it fixes the cause in src, reruns the test until it passes, and runs npm run lint with the sample's eslint.config.mjs. The fix stays inside the extension's own code: it does not raise engines.vscode to silence a missing API without saying so, and it does not catch and drop an error inside a provider, since VS Code already shows provider failures in the output channel. If the error depends on another extension or a workspace the sandbox cannot reproduce, the agent stops and reports what it tried.

## Start it with one API call

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

```json
{
  "agent": "claude",
  "input": "A Sentry alert fired for this VS Code extension; its payload follows this prompt. Use the Sentry connection to read the issue, its latest event, the VS Code and extension versions in its tags, and the stack frames. Map the frames from the compiled files under out back to src through the source maps tsconfig.json emits, and open the extension entry point and the provider or command handler the frames name. Add @vscode/test-cli, @vscode/test-electron, mocha and their types as dev dependencies if the package has none, with a .vscode-test.mjs that points at out/test, and write a test under src/test that activates the extension in VS Code and reproduces the error with the document, command or setting the event implies. Run npm run compile and xvfb-run -a npm test, fix the cause until the test passes, then run npm run lint. Open a pull request that links the Sentry issue, quotes the frames and the failing test output, and explains the cause. If the error does not reproduce, stop and report what you tried. Change nothing unrelated to this error.\n\nAlert payload:\n{payload}",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ],
  "connections": [
    "sentry"
  ]
}
```

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

The result is a pull request with a small diff: the source file where the error started, a new test under src/test, and where the sample had no runner, the test dependencies, a test script and .vscode-test.mjs in that sample's package. The description links the Sentry issue, names the function and the line in src that the frames mapped to, shows the test failing before and passing after, and explains the cause in plain words, such as a provider that assumed an open editor or a configuration value read before the extension activated.

The session holds the Sentry queries, the npm install, the compile, each xvfb-run test pass with its output and the lint run, plus the files the agent read. Its final message, also delivered as result in the run.completed webhook, is the short account a reviewer reads first.

Before merging, the reviewer confirms that the test activates the extension the way the event did rather than calling the function directly, that engines.vscode still matches the oldest VS Code the extension supports, and that the fix does not swallow errors a user would need to see. A different approach is a follow-up message to the same session, and the agent amends the branch.

## Run it on every new Sentry issue

Add an alert rule in Sentry for the extension's project that fires when a new issue is created, with a webhook action aimed at a handler on your server. The handler sends this request with the alert's JSON after the prompt and the issue id as the Idempotency-Key, so Sentry's retries map to one run and each issue gets its own sandbox, test and pull request.

Give the API key a webhook URL and Rush POSTs run.completed when the turn ends, with session_url to read the pull request from. The handler can instead call a webhook trigger on an automation in the Project, forwarding the alert body with the trigger's secret as the bearer token, because Sentry cannot send that header itself.

## Why run it on Rush?

Reproducing an extension host error means downloading a VS Code build, running it under a virtual display and driving it from a test, which is slow and leaves a .vscode-test directory and browser processes behind on a laptop. In a Rush sandbox the agent does that on its own machine with xvfb, as many times as the fix needs, and your editor keeps running.

The pull request carries the failing test, the passing test and the full command record, so the claim that the error reproduced can be checked rather than trusted. Each Sentry issue runs in its own sandbox, in parallel up to the key's concurrency limit, so a release that broke several commands gets several reviewed fixes at once.

## Frequently asked questions

### The frames point at out/extension.js. Can it find the source line?

Yes. tsconfig.json emits source maps beside the compiled files, so the agent maps each frame back to src and says in the pull request which frames it mapped and which it inferred from function names. Uploading those maps to Sentry with each release makes the next event name src directly.

### Does the test need a real VS Code?

Yes. @vscode/test-cli downloads a VS Code build and runs the mocha suite inside its extension host, which is the only way to activate the extension and call a provider the way the user did. The sandbox runs it under xvfb-run because VS Code needs a display.

### My extension has no tests at all. What does it add?

The same setup the test-cli sample uses: @vscode/test-cli and @vscode/test-electron with mocha, a test script that runs vscode-test, a pretest that compiles, and a .vscode-test.mjs listing out/test. The first test is the reproduction of this error, and later runs add to it.

### What if the error only happens with another extension installed?

The agent can install that extension into the test instance when the prompt names it; otherwise it reports that the reproduction needs it and stops rather than guessing. A follow-up message with the extension id lets the same session try again.
