# Fix a Failing CI Build in a TypeScript Project

Yes. A failed workflow starts an agent that reads the log, reruns the same build and Vitest command in a sandbox and opens a pull request with the fix.

[Run this on Rush](https://cloud.getrush.ai/run/fix-failing-ci/typescript/), in a Project that has your repository.

## What the agent does

A failed workflow on the default branch starts the run. The event gives the agent the workflow name, the head commit and the failing check runs, which in a TypeScript library already say a lot: a matrix job named for a TypeScript version, a lint job or a circular-import check. It clones the commit into its sandbox and reads the failed job's log with `gh run view --log-failed`.

In a library like `colinhacks/zod`, `.github/workflows/test.yml` has three jobs. `test-node` installs with `nub install --frozen-lockfile`, runs `nub run build`, swaps in TypeScript 5.5, 6 or latest with `nub add typescript@<version> -Dw`, then runs `nub run test` and the `@zod/resolution` and `@zod/integration` suites. `lint` runs `format:check` and `lint:check` (both Biome) and `check:comments`. `check-circular` runs `madge --circular` over `packages/zod/src`. The root `package.json` declares `"packageManager": "nub@0.8.3"`, `.nvmrc` says Node 24, and the workspace lockfile is `pnpm-lock.yaml`.

The agent reproduces the exact matrix leg. A failure only on `typescript@latest` is installed that way before running anything, because Zod's `vitest.config.ts` turns on Vitest typecheck with `checker: "tsc"` and `ignoreSourceErrors: false`, so a type error in a `.test.ts` file fails the suite even when every runtime assertion passes. It also loads `scripts/fail-on-console.ts` as a setup file, so a stray `console.log` fails a test. The agent runs the one failing project or file first, then the full `nub run test`.

It fixes the cause in `packages/zod/src/` or in the test the commit broke: a type that a newer compiler narrows differently, an import cycle `madge` found, a Biome rule the change violates. Before opening the pull request it reruns build, test, `format:check`, `lint:check` and `check:circular`, the same set CI runs.

## Start it with one API call

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

```json
{
  "agent": "claude",
  "input": "The GitHub Actions run on the default branch failed; the event follows this prompt. Read the failed job's log and name the job, the Node and TypeScript versions, and the failing test, type error or check. Install with the package manager and frozen lockfile the repository declares, match that TypeScript version, reproduce the failure with the job's exact command, and fix the cause. Then run the build, the tests, the formatter check and the linter. Open a pull request that quotes the failing log lines and explains the fix. Do not skip, mark flaky or delete a failing test, and do not add @ts-ignore or @ts-expect-error to get a type check through.",
  "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 a pull request whose description names the job and its TypeScript version, quotes the `tsc` or Vitest error with file and line, and shows that command failing and then passing in the sandbox. A change to `package.json`, the lockfile or `tsconfig.json` is called out separately from the source fix.

The full matrix runs again on the pull request, so a reviewer sees TypeScript 5.5, 6 and latest all green rather than taking the sandbox's word for the version it ran. They check that no `@ts-ignore`, `@ts-expect-error`, `.skip` or `any` cast arrived with the fix, and that a type change in a published package is one consumers can absorb.

When a failure depends on something outside the repository, such as a newly published TypeScript nightly behaving differently, the run reports what changed and where, so the decision to pin or adapt is made by a person with the evidence in front of them.

## Run it on every failed test workflow on main

Add an automation to the Project for this repository with the prompt above and a `github` trigger on `workflow_run.failure`, branch pattern `main`. One failed `test` run with several red matrix legs is one event, so it starts one agent run that sees every failing check name at once.

Redelivered events are dropped, forks are ignored, and the runs-per-hour limit stops a broken `typescript@latest` release from starting a run per repository faster than you choose.

## Why run it on Rush?

Fixing a TypeScript matrix failure by hand means installing the right package manager, matching a compiler version you may not have, and rerunning a build and a type-checked test suite that can take a while on a large workspace. A Rush run does that in its own sandbox and keeps each command's output, so the reviewer can read the exact `tsc` error before the fix and the clean run after it.

A new TypeScript release can break type tests in many libraries in one day. Each failure gets its own run on its own branch at the same time, nothing touches a developer's local `node_modules`, and each ends in a pull request whose matrix proves the fix, or a report that says why there is none yet.

## Frequently asked questions

### Does it work with pnpm, npm, Yarn or Bun?

Yes. It reads `packageManager` and the lockfile and installs with that tool and its frozen-lockfile flag, the same way the workflow does. Zod's `nub` is installed from the version the repository pins.

### Will it add @ts-ignore to get the type check through?

No. The prompt forbids `@ts-ignore` and `@ts-expect-error` as a fix, and Vitest typecheck with `ignoreSourceErrors: false` would still report source errors. A suppression in the diff would be the first thing a reviewer sees.

### Can it fix a failure that only happens on one TypeScript version?

Yes. It installs that exact version, as the matrix job does with `typescript@5.5` or `typescript@latest`, reproduces the error, and then checks the fix against the other versions the workflow tests.

### What if lint fails, not the tests?

It runs the lint job's own command, Biome's `check` and `lint` in Zod, and fixes the code the rule flags instead of changing `biome.jsonc`. A rule change, if the agent thinks one is right, is proposed separately in the description.
