Troubleshooting
When something doesn’t work
Most things that look like bugs in Strazh are either a setup step that got skipped or a deliberate safety/gate control doing exactly what it’s designed to do. This page walks through the most common ones: what causes each, and how to fix it.
Getting Started
Strazh says Claude Code, Codex, or Cursor isn’t available, even though you have it installed.
Strazh dispatches to these three agents as local CLI subprocesses, and it can only find them if the CLI binary is resolvable on your system PATH. If the CLI was installed into a shell profile that Strazh’s desktop process doesn’t inherit (a common case on Windows, where npm-installed CLIs land as `.cmd` wrapper scripts), Strazh won’t see it even though a terminal you opened yourself can run it fine.
Confirm you can run the CLI from a plain terminal window first (e.g. `claude --version`, `codex --version`, `cursor-agent --version`). If that works but Strazh still reports it unavailable, fully quit Strazh via the tray icon (not just close the window) and relaunch. PATH is read at process start, so a CLI installed after Strazh was already running won’t be picked up until restart. If it still isn’t found, reinstall the CLI and confirm the installer added it to the system PATH, not just a shell-specific rc file.
Devin shows as unavailable in the agent list.
Devin is different from the other three agents: it isn’t a local CLI at all, it’s Cognition’s cloud-hosted session API. Strazh checks for a configured Devin API key rather than checking PATH, so “unavailable” here almost always means no key is set, not a missing install.
Add your Devin API key in Strazh’s settings. Once it’s set, Strazh can derive the repo/branch identity from your local working directory (via `git remote get-url origin` and the current branch) and dispatch to Devin’s hosted session API. Devin doesn’t run anything locally, so there’s nothing to install beyond the key itself.
App Startup
The app window opens but nothing loads, or it hangs on a blank/loading screen indefinitely.
Strazh’s gate logic runs in a local backend process that the desktop app spawns on startup. If that process fails to launch, most commonly because antivirus/firewall software is blocking it, or another process is already bound to its local port, the frontend has nothing to talk to.
First, just restart the app. Transient startup failures are usually resolved by relaunch. If it persists: check that your antivirus or firewall isn’t quarantining or blocking the Strazh backend process or its local network connection (allow it if prompted). Also check for a port conflict: another application may already be using the local backend port; closing that other application and relaunching Strazh often resolves it. If none of that works, a full reboot clears most lingering port/process locks.
The app was closed but a background process or tray icon is still running, or a restart doesn’t actually restart the backend.
Strazh keeps a system tray icon running by design so the app can be quickly restored, and closing the main window hides it rather than fully quitting. This is intentional: “closing the window” only hides the app, and “quitting the app” requires a separate action.
To fully quit Strazh (and its backend), right-click the tray icon and choose Quit, rather than just closing the window. If you suspect a stuck process is preventing a clean restart, quit fully via the tray menu first, then relaunch.
Licensing
License activation fails with an invalid or rejected token, even though you have an active subscription.
License activation is verified fully offline against a public key baked into the desktop app: it does not phone home, so an internet outage is not the cause of an activation failure. The far more common causes are a copy-paste error in the license token (extra whitespace, a truncated paste, missing characters) or a license that’s genuinely expired or been deactivated on your account.
Re-copy the license token from your account dashboard, taking care to select the whole string, and paste it fresh into Strazh rather than editing a previous paste. If it still fails, log into the account portal and check your license/subscription status directly. If it shows expired or deactivated there, that’s the real cause and needs to be resolved on the billing side (portal dashboard) before the token will verify locally.
Activation succeeded before but Strazh has now silently dropped back to Free-tier behavior.
This can happen if your license genuinely expired or was deactivated. It is not caused by a network blip: offline verification means Strazh doesn’t need to reach the internet to keep validating an already-activated license.
Check your license status in the account dashboard first. If your subscription is active there but Strazh still shows Free-tier limits (the 5-dispatch daily cap), try deactivating and reactivating the license in Strazh with a freshly copied token, following the same copy-paste care as above.
Dispatch / Gate
Dispatching a coding agent from Runs is rejected before it even starts, with a “cwd not allowed” reason.
This is a deliberate safety control, not a bug. Strazh’s gate only allows dispatch into working directories that have been explicitly registered on your allow-list. This prevents a dispatched agent from touching arbitrary filesystem locations outside repos you’ve approved. Every rejected attempt is durably logged with the reason, the path, and the timestamp, so this isn’t a silent failure either.
Check that the repository path you’re targeting is actually on your allow-list (Strazh’s repo/workspace settings). If it isn’t, add it there first, then retry the dispatch from Runs. If the path is already allow-listed and dispatch is still rejected, check whether you’ve hit the daily dispatch cap instead (see the next entry): the rejection reason shown in the run feed tells you which one it is.
Dispatch is rejected specifically on Free tier after a few successful runs earlier the same day.
Free tier enforces a hard daily cap of 5 dispatches. Once used up, further dispatch attempts are rejected until the cap resets. This is logged the same as any other rejection, with the cap-hit reason.
Wait for the daily cap to reset (24 hours from your first dispatch that day), or upgrade to Individual Pro for 35/day plus metered overage at $0.01/dispatch beyond that, or Enterprise for uncapped dispatch (sold sales-assisted, contact us). This is a tier limit working as intended, not an error condition to debug.
A dispatch in Runs just sits there and never completes, eventually failing after a long wait.
This is a known gap with headless Claude Code dispatch specifically. A non-interactive `claude -p` invocation can still hit an interactive permission prompt (for Bash/Read tool use) that a piped subprocess can never answer. Strazh deliberately doesn’t pass permission flags, since the target repo’s own Claude Code config is meant to govern that. Left unanswered, the dispatch hangs until Strazh’s timeout (around 15 minutes) and is then tree-killed.
Add a `.claude/settings.json` file in the target repo with `{"permissions": {"allow": ["Bash"]}}`: this pre-grants the permission so headless dispatch doesn’t stall waiting for an answer that can never come. If a run does hang, you don’t need to force-quit anything: Strazh’s process-tree-aware kill will clean it up automatically once the timeout is reached, or you can stop it manually from the run feed.
MCP Mode
An external client (Claude Desktop, Cursor, Codex CLI) can’t connect to Strazh as an MCP server.
Strazh’s MCP server is a single local HTTP endpoint (`POST /mcp`, JSON-RPC 2.0) served by the same local process the desktop app talks to. It comes up automatically with the desktop app, or standalone via `python -m strazh.server` if you’re not running the desktop app at all. Either way, if nothing’s serving on that port, there’s nothing to connect to. Beyond that, MCP mode is free on every tier including Free, so a missing license is not the cause of a connection failure. The most client-specific gotcha is Claude Desktop: it only supports stdio-based MCP servers, not a local HTTP server, so it cannot connect to Strazh directly no matter how the port is configured.
First confirm something is actually serving, either the desktop app (check the tray icon) or a standalone `python -m strazh.server`, and that the local port (8765 by default) hasn’t changed or been blocked by antivirus/firewall (same check as the backend-startup issue above). Every request, MCP included, requires the `X-Strazh-Token` header the server prints on startup; a connection that reaches the port but gets rejected is almost always a missing or stale token. For Claude Desktop specifically, you must use the mcp-remote bridge in its config to translate stdio to Strazh’s local HTTP endpoint. Pointing Claude Desktop’s config directly at the HTTP address will not work, that’s a protocol mismatch, not a bug. Clients that do support HTTP-based MCP servers (Cursor, Codex CLI) can point at `http://127.0.0.1:8765/mcp` directly, with that token header set, once the server is confirmed running. A dispatch triggered this way goes through the exact same allow-list and daily-cap gate as a dispatch started from Runs. There’s no separate, less-guarded path for MCP clients.
General
None of the above matches what you’re seeing, or you’re not sure if something is a bug or expected behavior.
Not every issue is covered by a specific troubleshooting entry, and some things that look like bugs (cwd rejections, daily-cap rejections, MCP Desktop’s stdio-only limitation) are intentional design decisions rather than defects.
Check the FAQ page first for quick answers to common questions. If your issue looks like an actual defect rather than expected behavior, search the project’s GitHub repository for existing issues before filing a new one: someone may have already hit and documented the same thing. For anything else, use the Contact page to reach the team directly.