# Troubleshooting

Start with `hushrun whoami`: it shows where results go here, what named that backend, which credential goes with it, and what the backend says about it. Add `-v` to any command for more of hushrun's reasoning on stderr.

## A check runs every time

hushrun skips only when it finds a pass for the same key. When a check keeps running:

- **The files differ.** Something changes the repository on every run: a generated file, a lockfile your install rewrites, or the check's own output. Commit or ignore it. If the check writes files, hushrun says `files changed while it ran, so it wasn't recorded`: list them in `.gitignore`.
- **The command differs.** Extra arguments, another directory or another name make another key. `npm test -- --coverage` is not `npm test`.
- **Nobody has recorded a pass yet.** The first run of each check on new code always runs, and so does the first run after a failure.
- **Results go nowhere shared.** `hushrun whoami` says `this machine only`, or a line says `sign in to share results`: sign in with `npx hushrun login`.
- **Results are off.** `HUSHRUN_BACKEND` is set to nothing, or `HUSHRUN_CACHE_DIR` is.
- **`hushrun.yaml` has several scopes.** hushrun says `can't tell which code this is`: add `--scope NAME` to the check's command.
- **CI ignores laptops' passes.** In CI, a line ending `skipped only on CI's passes` means the repository has [CI reuses only CI's results](https://hushrun.com/docs/ci.md#ci-only) turned on: CI skips only checks CI itself passed.
- **Your organization's plan is at its limit.** A line ending `; upgrade: …` means new results aren't recorded until the period ends or an admin upgrades. See [Plans and limits](https://hushrun.com/docs/plans.md).

## A check skipped when it shouldn't have

A skip means the same check, with the same command, passed on exactly these files. If a check's result also depends on something outside the files, such as an environment variable, a service, the Node.js version or the operating system, give each variant its own name, such as `unit-node22`. To run a check once more and record the new result, use `--force`:

```bash
npx hushrun run --force test -- vitest run
```

## Sign-in and credentials

| Line | What to do |
|---|---|
| `hushrun: sign in to share results with acme: npx hushrun login` | Sign in once on this machine |
| `hushrun: results aren't shared with acme: …` | Nothing on this run could sign in: no login, no `HUSHRUN_TOKEN`, and in GitHub Actions no `id-token: write`. In a script or a sandbox, set `HUSHRUN_TOKEN` ([Agents and sandboxes](https://hushrun.com/docs/agents.md#sandboxes)); in GitHub Actions, add `id-token: write` to the job ([In CI](https://hushrun.com/docs/ci.md)) |
| `hushrun: test running: acme refused your login: …` | Your sign-in no longer works there, for example because you left the organization. Sign in again with `hushrun login` |
| `hushrun: test running: acme refused HUSHRUN_TOKEN: … expired on …` | Create a new agent token under the same name, and update the variable |
| `hushrun: test running: acme refused this job's ID token: …` | The backend doesn't accept this repository's CI: check that the repository is connected to the organization, and that it wasn't deleted and created again under the same name |
| `hushrun: HUSHRUN_TOKEN isn't sent to …` | The token goes only to the backend `HUSHRUN_BACKEND` names, and an agent token to hushrun's hosted service. Set `HUSHRUN_BACKEND` to the backend's URL |
| `not signed in: …`, with a link to your machines page | You have 20 machines in that organization, the most it takes. Revoke one you no longer use on that page, `https://app.hushrun.com/account/machines`, then run `hushrun login` again |
| `not signed in: …`, saying this machine was revoked | You or an admin revoked this machine in the dashboard, and a revoked machine doesn't come back. Remove the key file the message names, then run `hushrun login`: hushrun makes a new key. Sign in again in your other organizations too, since they knew the old key |

A pull request from a fork gets no ID token from GitHub, so its checks run and record nothing. That is expected.

## Results that aren't recorded

These lines end a run that passed or failed as usual, with its exit code kept:

| Line | What to do |
|---|---|
| `test passed in 41s; not recorded: …; upgrade: https://app.hushrun.com/acme/-/billing` | The organization recorded every check its plan includes this period. An admin upgrades at that page, or the next period starts over |
| `test passed in 41s; not recorded: agent token … recorded 300 results in the last minute, its limit` | Slow the fleet down, or create its token with a higher `--rate` |
| `test passed in 41s; not recorded: agent token … records results for github.com/acme/shop only, and this result is for …` | Use that repository's token, or one made with `--org-wide` |
| ``test passed in 41s; not recorded: this machine isn't registered: run `hushrun login` `` | Run `hushrun login` on this machine. A result from your sign-in carries this machine's signature, and the server takes none without it: the machine has no key yet, its registration was revoked, or it went 90 days unused, which signing in again undoes |
| ``test passed in 41s; not recorded: set `HUSHRUN_MACHINE_KEY` to the key `hushrun token create --agent` printed`` | The job or sandbox has an agent token but not the key it came with. Set `HUSHRUN_MACHINE_KEY` to the key shown with the token, or `HUSHRUN_MACHINE_KEY_FILE` to a file that holds it. If nobody kept it, create a new token ([Agents and sandboxes](https://hushrun.com/docs/agents.md#sandboxes)) |
| `test passed in 41s, but it couldn't be recorded (…)` | The backend couldn't be reached. The next run on this code runs again |
| `test passed in 12s, but files changed while it ran, so it wasn't recorded. …` | List what the check writes in `.gitignore` |

## The backend can't be reached

```text
hushrun: test running: can't read earlier results (https://api.hushrun.com/o/acme: v0/results/…: error sending request: …)
```

hushrun gives a run's requests 10 seconds in all, then runs the check, and still tries to record the result. Nothing fails because a backend is down. `hushrun whoami` exits 6 when it can't reach the backend.

## The command doesn't start

```text
hushrun: can't start vitest: No such file or directory (os error 2)
```

hushrun exits 127, as a shell does, when the command isn't found, and 126 when it can't start it. Run wrapped scripts through your package manager (`npm test`), which puts `node_modules/.bin` on the `PATH`, or call the command by its path.

## A variable is ignored

```text
hushrun: HUSHRUN_NO_CI_OUTPUT is "maybe", not true or false, so it's ignored
```

hushrun couldn't read the variable, so the command goes on as if it weren't set, and exits as it would have. It usually means a CI setting holds a typo, or a value meant for something else. Fix the value or remove the variable; `-q` hides the line. What each variable takes is in [Environment variables](https://hushrun.com/docs/reference/environment.md).

## init

| Message | What to do |
|---|---|
| `hushrun init sets up a git repository: run it inside one` | Run it inside a git repository, at its root |
| `init can't ask without a terminal: run hushrun init --yes to apply` | In a script or as an agent, add `--yes` |
| `… the sign-in wasn't approved for an organization …` | Create or join an organization in the dashboard, then run init again |
| `… isn't a member of acme.` | The repository already records to an organization you aren't in. init offers to ask its admins to let you in; once one approves, run init again |
| `… is invited to acme: accept the invitation …` | Accept the invitation in the dashboard, then run init again |
| `This repository already uses hushrun: …` | Nothing to set up; init still makes sure the organization has the repository |

init changes files only after you agree, or with `--yes`, and only the lines it listed. `git diff` shows them before you commit.

## Still stuck

`hushrun doctor` checks the whole setup: git, CI, where results go, and the credential. Its output, with `hushrun whoami` and the run's lines, says almost everything about why hushrun did what it did.
