Browse docs
Docs /reference/troubleshooting
Reference

Troubleshooting

Find the symptom. Each one names a concrete cause and fix.

My run is stuck on PENDING forever

Nothing is draining the queue.

Triggering a run enqueues a Redis job. If no runner is consuming that queue, the run sits at PENDING indefinitely and nothing surfaces an error — the job was accepted, it's just never picked up.

The API detects this: a runner-presence watchdog logs a WARN once the queue stays non-empty for more than 60 seconds. Check the API logs first.

  • Self-hosted: the runner is a separate service. API + web is not a complete stack. See self-hosting.
  • Local development: pnpm dev:api and pnpm dev:web don't start it. Use pnpm dev (which runs everything) or add pnpm dev:runner in a second terminal.

I get a 401 with a token I know is valid

Check the izri_ prefix.

The API short-circuits to bearer validation only when it sees izri_. Anything else falls through to cookie-session handling and returns an opaque 401 with no explanation.

A truncated copy-paste that lost the prefix looks exactly like an expired token. Verify the value before assuming the token is bad.

I get a 404 for a project ID I'm certain exists

The token probably belongs to a different organization.

Cross-organization access returns 404, not 403 — deliberately, so the API doesn't confirm a resource exists to someone who can't reach it.

Run list_projects (MCP) or check the dashboard to see what your token can actually reach.

The Action can't find my project

Resolution order is --project / project-idIZRI_PROJECT_ID → auto-match on the git origin remote.

Auto-match fails when:

  • there is no origin remote, or it isn't GitHub
  • the repository isn't bound to a project yet
  • the token is in a different organization (see above)

Pass project-id explicitly to rule it out.

The scope check fails immediately in CI

fetch-depth: 0 is missing.

- uses: actions/checkout@v4
  with:
    fetch-depth: 0

The scope check diffs against origin/<base>. actions/checkout defaults to a shallow clone with no base ref, so the diff can't be resolved. This is the single most common CI setup failure.

izri check-scope produces a strange diff locally

The default base is origin/main.

If your trunk is master, develop, or anything else, pass it:

izri check-scope --base origin/develop

Wrong base gives you a wrong diff rather than an empty one, which is why the result looks strange rather than obviously broken.

My .izri/scope.yml seems ignored

Two possibilities.

It's malformed. A file that doesn't parse falls back to the dashboard config or defaults and emits an info-level finding. info doesn't block, so it's easy to miss. The delta report records which source was used — in_repo, dashboard, or defaults. If it says anything but in_repo, your file didn't parse.

It isn't at the PR head. Resolution reads the file from the head commit. Adding it to main after opening the PR won't apply until you merge or rebase.

A sensitive path was touched and nothing failed

Working as designed. sensitive_path is emitted at info — a "look here" pointer, not a gate.

If you want a genuine block, express it as forbids on a category in .izri/scope.yml. That emits pr_type_forbidden_category at error, which is a hard rule.

Tests pass but izri/hallucination fails

Working as designed, and this is the signal's whole purpose.

Your tests passed without executing the lines you changed. change_uncovered is a hard rule, so it fails the umbrella regardless of a green suite.

The per-file detail lists exactly which lines went unexercised. Write a test that reaches them. See izri/hallucination for a worked example.

Login redirects in a loop with no error

The OAuth callback URL doesn't match the configured app URL.

A port mismatch between where your browser reaches the app and where Izri thinks it lives produces a silent redirect loop rather than an error message. Make them match exactly.

izri/visual reports no_baseline on everything

Expected on the first run. There is nothing to compare against yet. That run establishes the baseline; the next one can detect regressions.

Visual diffs report tiny changes I didn't make

Differences under 0.1% are treated as matched precisely because anti-aliasing and sub-pixel font rendering produce 0.01–0.05% noise between identical runs. If you're seeing reported diffs above that, something did change — check dimensions_changed, which means the viewport or element size shifted and made the comparison ill-defined.

The umbrella is unknown

Not enough signal: the delta is still in flight, or every child skipped. Treat it as "wait", not "go". Branch protection blocks on it without marking it failed, which is correct.

A run errored instead of failing

ERROR means the run itself broke rather than tests failing. It is treated as an analyzer error — a hard rule — because no evidence must never be read as "safe".

Check the run logs. Common causes are a missing dependency in the test environment or a timeout.

Still stuck

Every page here is available as raw markdown — append .md to any URL — and the whole corpus is at /llms-full.txt if you want to hand it to an agent.

Reading this with an agent? /docs/reference/troubleshooting.md serves the raw markdown.

Edit this page on GitHub →All docs