# Common Troubles

This page is a reference for errors `forge` can print on your own machine —
not a status page for the service, since there isn't one. If your environment
is behaving strangely and you don't see it below, run `forge doctor` first —
it's a read-only check that catches most of the causes on this page before
you have to go hunting:

```sh
forge doctor
```

## Install & Upgrade

### `forge upgrade` fails with "permission denied"

**Symptom**

```
extract forge: create /usr/local/bin/forge.new: open /usr/local/bin/forge.new: permission denied
```

**Cause**: `/usr/local/bin` is owned by `root` and the current user can't write
to it.

**Fix**: run the upgrade elevated, or fix ownership once so you never need
`sudo` for this again:

```sh
sudo forge upgrade
```

See the ownership fix under [Install the binary](/installation#install-the-binary).

### Checksum mismatch on the downloaded archive

**Symptom**

```
checksum mismatch for forge_1.2.3_darwin_arm64.tar.gz:
  expected: <hex>
  got:      <hex>
```

**Cause**: the download was corrupted in transit, or a proxy/CDN between you
and the release repository is serving mutated bytes.

**Fix**: retry the download. If it keeps failing, check whether you're behind
a corporate proxy that rewrites binary responses, and try from a different
network. See [Verify the download](/installation#verify-the-download).

### `checksums.txt unavailable`

**Symptom**

```
checksum verification failed: checksums.txt unavailable: download https://api.github.com/.../checksums.txt: HTTP 404
```

**Cause**: no network connectivity, a GitHub outage, or a missing/invalid
token against forge's private distribution repository.

**Fix**: check your connection first, then set a token:

```sh
export GITHUB_TOKEN=<your-token>
# or
gh auth login
```

### Asset not found in a release

**Symptom**

```
asset "forge_1.2.3_linux_amd64.tar.gz" not found in github release v1.2.3
```

**Cause**: that release is still building, or that OS/architecture wasn't
published for this tag.

**Fix**: wait a few minutes and retry, or download the asset manually from
the [releases page](https://github.com/Maistik-Studio/forge-kit/releases).

### Windows: manual update required

**Symptom**: `forge update` reports a newer version is available but can't
apply it automatically for a given managed tool.

**Cause**: not every tool supports in-place self-replacement on Windows the
way `forge` itself does with its PowerShell installer.

**Fix**: download the release asset manually from the URL `forge update`
prints, and replace the binary yourself.

## Homebrew-Specific

### `forge: command not found` after a clean `brew install forge`

**Symptom**

```
$ brew install forge
==> Fetching forge
==> Installing forge
🍺  forge was successfully installed!
$ forge version
zsh: command not found: forge
```

**Cause**: `forge` collides with an unrelated `homebrew-core` formula
([arrayfire/forge](https://github.com/arrayfire/forge), a C++ visualization
library that ships no CLI binary). If `brew tap maistik-studio/forge
https://github.com/Maistik-Studio/forge-kit` was skipped, or ran but failed
silently because `HOMEBREW_GITHUB_API_TOKEN` wasn't set (the release
repository is private), `brew install forge` resolves against
`homebrew-core` instead. Homebrew reports success because that install genuinely
succeeded — it just installed the wrong package.

**Fix**:

```sh
brew uninstall forge
export HOMEBREW_GITHUB_API_TOKEN=<your-token>   # GitHub token, not GitLab
brew tap maistik-studio/forge https://github.com/Maistik-Studio/forge-kit
brew install forge
```

To avoid the ambiguity entirely, always install fully qualified:

```sh
brew install maistik-studio/forge/forge
```

### Untrusted tap

**Symptom**

```
Homebrew requires explicit trust for external taps. Trust only this Forge <formula/cask>, then retry:
  brew trust --formula gentleman-programming/tap/<tool>
  brew upgrade --formula <tool>
```

**Cause**: Homebrew now requires an explicit trust step for third-party taps
before it will install or upgrade from them.

**Fix**: run the two commands `forge` printed — `brew trust`, then
`brew upgrade` — and retry.

### Linux sandbox failure

**Symptom**

```
Bubblewrap ... cannot create a rootless sandbox
```

**Cause**: unprivileged user namespaces are disabled at the kernel level, so
Homebrew's Bubblewrap sandbox can't start.

**Fix**: enable user namespaces:

```sh
sudo sysctl -w kernel.unprivileged_userns_clone=1
```

As a last resort, skip the sandbox for this run:

```sh
HOMEBREW_NO_SANDBOX_LINUX=1 brew upgrade --formula <tool>
```

## Network & Private-Repo Authentication

### Private-repo authentication required

**Symptom**

```
private repo, no GitHub token configured — set GITHUB_TOKEN to check
```

```
private repo, no GitLab token configured — set GITLAB_TOKEN to check
```

**Cause**: forge's distribution repositories are private. Without a token,
"the release doesn't exist" and "you're not authenticated" both come back as
an HTTP 404, so forge reports the auth-required case rather than guessing.

**Fix**: set the token for whichever host the tool in question is
distributed from:

```sh
export GITHUB_TOKEN=<your-token>   # or: gh auth login
export GITLAB_TOKEN=<your-token>   # CI_JOB_TOKEN is picked up automatically inside CI
```

### GitHub API rate limit exceeded

**Symptom**

```
github API rate limit exceeded (HTTP 403)
```

**Cause**: unauthenticated GitHub API requests are capped at 60/hour per IP.
Frequent `forge status` / `forge sync` calls, or a shared office IP, exhaust
that quickly.

**Fix**: set `GITHUB_TOKEN` (raises the cap to 5,000/hour), or wait for the
window to reset.

## Configuration

### Malformed `.forge/config.yaml`

**Symptom**

```
parse .forge/config.yaml: yaml: line 12: did not find expected key
```

**Cause**: hand-edited YAML with bad indentation or syntax.

**Fix**: fix the syntax, or avoid hand-editing entirely — use
`forge config edit` for an interactive TUI. `forge config explain` shows the
fully resolved values without editing anything.

### Unknown config key

**Symptom**

```
"workflow.styct_tdd" is not a recognized config key; run `forge config explain` to see the resolved keys
```

**Cause**: a typo in a config key, usually from hand-editing.

**Fix**:

```sh
forge config explain
```

Find the correct key name and fix the typo.

### Invalid `review.gate` value

**Symptom**

```
review.gate must be one of ci, off, pre-commit, pre-push, not "precommit"
```

**Cause**: an unsupported value was set for `review.gate` — the missing
hyphen above is a common one.

**Fix**: use one of `ci`, `off`, `pre-commit`, or `pre-push`.

### `forge config edit` without a terminal

**Symptom**

```
forge config edit needs an interactive terminal; use `forge config set <key> <value>` in scripts and CI
```

**Cause**: `config edit` is an interactive TUI and can't run in a script or
CI job with no TTY attached.

**Fix**: use the non-interactive form instead:

```sh
forge config set <key> <value>
```

### Unsupported flag value

**Symptom**

```
unsupported persona "gentelman"
unsupported preset "min"
unsupported sdd-mode "solo" (valid: single, multi)
```

**Cause**: an invalid value was passed to `--persona`, `--preset`,
`--components`, `--skills`, or `--sdd-mode` — often a typo.

**Fix**: run `forge install --help` to see the valid IDs for each flag.

## Backups & Restore

### Corrupted backup manifest

**Symptom**

```
unmarshal manifest ".forge/backups/upgrade-.../manifest.json": invalid character '\x00' looking for beginning of value
```

**Cause**: the backup was interrupted mid-write — disk full, process killed,
or power loss during the snapshot.

**Fix**: use a different, uncorrupted backup:

```sh
forge restore --list
```

Delete the corrupt backup directory under `.forge/backups/`.

### No matching backup ID

**Symptom**

```
backup "20260101T000000Z" not found — use `forge restore --list` to see available backups
```

**Fix**:

```sh
forge restore --list
```

Pick an ID from the printed list.

### No backups available

**Symptom**

```
no backups available to restore
```

**Cause**: this is expected on a fresh install, or if backups were disabled
with `--no-backup` on the operation that ran. It isn't a bug.

### Pre-upgrade backup fails, but the upgrade proceeds anyway

**Symptom**

```
pre-upgrade backup failed — upgrade will run without a backup: create archive ".../snapshot.tar.gz": open .../snapshot.tar.gz: no space left on device
```

**Cause**: the backups directory is on a full or read-only volume. This is
intentionally non-fatal — forge upgrades anyway rather than blocking you on a
backup failure.

**Fix**: free up disk space, or fix permissions on the backups directory, if
you want the safety net back for the next operation.

## Dependencies & Environment

### Missing agent runtime dependency

**Symptom**: forge blocks the install for a given agent, e.g.:

```
Node.js / npm is required but 'npm' was not found in PATH...
Kimi requires Astral uv, but 'uv' was not found in PATH...
Pi requires the 'pi' executable in PATH before installing Forge Pi packages
```

**Cause**: each agent has its own runtime prerequisite that forge checks
before writing its configuration.

**Fix**:

| Agent(s) | Requires | Fix |
| --- | --- | --- |
| Claude Code, OpenCode, Kilocode, Gemini CLI, Codex, Qwen Code | Node.js / npm | Install [Node.js](https://nodejs.org) |
| Kimi | Astral `uv` | `brew install uv`, or `sudo apt-get install -y uv`, or see [docs.astral.sh/uv](https://docs.astral.sh/uv/) |
| Pi | the `pi` executable, pre-installed | Install the Pi CLI first, then `forge install --agent pi` |

### `sudo npm install -g` prompts unexpectedly

**Symptom**: forge silently runs `npm install -g` under `sudo`, prompting
for your password when you didn't expect it.

**Cause**: on Linux, with a distro-packaged Node (not installed via nvm, fnm,
or volta), npm's global install prefix is root-owned — forge prepends `sudo`
so the install can succeed at all.

**Fix**: install Node via [nvm](https://github.com/nvm-sh/nvm), fnm, or
volta instead of your distro's package. That makes npm's global prefix
user-writable, and forge stops needing `sudo` for this.

### OpenCode plugin: no package manager found

**Symptom**

```
OpenCode plugin <pkg> can be upgraded from ~/.config/opencode, but no supported package manager is available in PATH. Install bun or npm, then run update tools again.
```

**Cause**: neither `bun` nor `npm` is on `PATH`, so forge has nothing to run
the upgrade with.

**Fix**: install [Node.js](https://nodejs.org) (for `npm`) or
[Bun](https://bun.sh).

### Go missing or too old

**Symptom**

```
Go 1.24+ is required to install Engram but was not found in PATH
Go 1.24+ is required to install Engram but found go1.20.
Go modules are disabled (GO111MODULE=off).
```

**Cause**: the Engram memory backend is installed via `go install`, which
needs a recent Go toolchain with modules enabled.

**Fix**: install or upgrade Go from [go.dev/dl](https://go.dev/dl/), and if
needed:

```sh
export GO111MODULE=on
```

### GGA upgrade: git clone failure

**Symptom**

```
git clone gentleman-guardian-angel: exit status 128 (output: ...)
```

**Cause**: `git` isn't installed, there's no network connectivity, or the
release tag doesn't exist yet (this can happen briefly right after a
release).

**Fix**: install `git`, check your connection, and retry — if it's a
just-published release, wait a few minutes first.

### `forge doctor` reports a missing ecosystem dependency

**Symptom**

```
node not found in PATH...
gga binary not found
```

**Cause**: a feature you've configured — MCP stdio servers, the review gate,
Engram memory — needs a CLI tool that isn't installed.

**Fix**:

```sh
forge doctor --fix
```

Or install the missing tool yourself and re-run `forge doctor`.

## Still stuck?

Run the full self-test for a deeper check than the read-only default:

```sh
forge doctor --selftest
```

If that doesn't explain what you're seeing, double check the
[Installation](/installation) steps, or
[open an issue on GitHub](https://github.com/Maistik-Studio/forge-kit/issues) —
it's the fastest way to reach the people building this.
