Troubleshooting¶
Common issues and their diagnostic paths.
Diagnostics reference¶
The framework's conf.d/68-diagnostics.zsh provides diagnostic
functions. The most important built-in diagnostics:
# mise self-check
mise doctor
# Show which tools are active and from where
mise ls
# Show the current git identity
git config --show-origin user.email
# Show all loaded SSH keys
ssh-add -l
# Verify SSH to GitHub
ssh -T git@github.com-work
ssh -T git@github.com-personal
# Show current PATH, one entry per line
path # alias defined in conf.d/60-aliases.zsh
# Benchmark shell startup
timeshell 10 # function from conf.d/80-functions.zsh
mise tool not found after installation¶
Symptom: mise install succeeds, but the tool is not on PATH.
Diagnostic:
mise ls # is the tool listed?
mise where ruby # where is it installed?
which ruby # which binary is the shell finding?
Common causes:
- Not trusted. Run
mise trustin the project directory. - Shims not on PATH. Check that
~/.local/share/mise/shimsis in your PATH (runpath). - IDE subprocess. The IDE didn't inherit the shell environment. See editors for the subprocess problem.
Wrong git identity on commits¶
Symptom: Commits show the wrong email address.
Diagnostic:
Common causes:
- Repository not under
~/development/work/or~/development/personal/. TheincludeIfdirectives in~/.config/git/configmatch on directory path. Clone work repos under~/development/work/repos/and personal repos under~/development/personal/repos/. - Legacy
~/.gitconfigexists. Delete it; the framework uses~/.config/git/configexclusively. - Trailing slash missing.
includeIf "gitdir:~/development/work/"requires the trailing slash.
SSH authentication failures¶
Symptom: Permission denied (publickey) when pushing to GitHub.
Diagnostic:
ssh -vT git@github.com-work # verbose output shows which keys are tried
ssh-add -l # which keys are loaded in the agent?
Common causes:
- Key not loaded. On macOS:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work. On Linux:ssh-add ~/.ssh/id_ed25519_work(omit--apple-use-keychain). IdentitiesOnly yesnot set. Without it, SSH offers every key in the agent; GitHub rejects after too many attempts.- Public key not registered. Add the
.pubfile contents to GitHub > Settings > SSH and GPG keys. - Wrong host alias. The git URL rewrite in the profile must
match the
Hostentry in~/.ssh/config.
Shell startup is slow¶
Symptom: New terminal takes more than 200ms to become interactive.
Diagnostic:
# External timing
hyperfine --warmup 3 "zsh -lic exit"
# Internal profiling
# Add to top of .zshrc: zmodload zsh/zprof
# Add to bottom of .zshrc: zprof
Common causes:
- Tool init running on every startup. Move deterministic init
output to the version-hashed cache in
25-tool-cache.zsh. See the performance page. - Stale compinit cache. Delete
~/.cache/zsh/zcompdump*and restart the shell. - Rogue eval in conf.d. Check
70-tools.zshfor tools that should be in25-tool-cache.zsh(Tier 2) instead.
direnv not loading .envrc¶
Symptom: cd into a project directory doesn't set environment
variables.
Diagnostic:
Common causes:
- Not allowed. Run
direnv allow(orda). - direnv not installed.
command -v direnv— it is declared in mise's[tools], somise installdelivers it; a missing binary usually means the toolchain install has not run yet. - mise handling the env. If you moved env vars to
mise.toml's[env]block, direnv is no longer needed for those variables.
op cannot talk to the 1Password desktop app¶
Symptom: op whoami (or any op command) fails with
connecting to desktop app: read: connection reset, even though the
desktop app is running and "Integrate with 1Password CLI" is enabled
in Settings → Developer.
Cause: on Linux the app verifies the calling binary before
accepting the connection: op must be group onepassword-cli with
the setgid bit (-rwxr-sr-x root onepassword-cli). The CLI's own
rpm/deb sets this; a mise/aqua-installed op is plain user-owned and
gets rejected. Worse, a mise [tools] entry shadows a correctly
installed /usr/bin/op because mise's install paths precede system
paths — so adding op to mise can break an integration that worked.
Diagnostic:
command -v op # mise path = shadowed; /usr/bin/op = system
ls -l /usr/bin/op # want: -rwxr-sr-x ... root onepassword-cli
rpm -qf /usr/bin/op # want: 1password-cli-<version>
Fix: op is a system package on Linux in this framework
(mise/config.linux.toml), NOT a [tools] entry — see the comment in
mise/config.toml for why. If a mise copy exists, remove it:
mise uninstall --all 1password && mise reshim
sudo dnf install 1password-cli # Fedora: repo ships with the desktop rpm
command -v op # now /usr/bin/op
op whoami # "account is not signed in" = integration OK; sign in via the app prompt
(macOS is different: the app checks the binary's code signature, which
the official zip keeps, so mise owns op there — mise/config.macos.toml.)
Applications are OOM-killed while memory looks fine¶
Symptom: VS Code (or another Electron app) dies mid-session,
sometimes several times a day. free -h afterwards shows several GB
available. journalctl -k | grep -i 'out of memory' confirms the
kernel OOM killer fired, and the process it names is the one that
died — not the one that ate the memory.
Diagnostic: the kernel logs a full task table at each kill. Read it, rather than guessing from the current state of the machine:
# When did it fire, and who got killed?
journalctl -k --since today | grep -E 'Out of memory|oom-kill'
# Who was actually holding memory at that moment? Sum the task
# table by process name (rss and swap columns are in pages; ×4/1024 = MB).
T='2026-08-22 15:36' # minute of the kill, from the line above
journalctl -k --since "$T:00" --until "$T:59" -o cat \
| grep -E '^\[ *[0-9]+\]' | sed 's/[][]/ /g' \
| awk 'NF>=12 {r[$12]+=$5*4/1024; s[$12]+=$10*4/1024; n[$12]++}
END {for (k in r) printf "%7.0f MB rss %7.0f MB swap x%-3d %s\n", r[k], s[k], n[k], k}' \
| sort -rn | head
# Is swap real, or only zram (compressed RAM)?
swapon --show
zramctl
Common causes:
- zram is the only swap. Fedora's default
zram-generatorgives you 8 GB of compressed-in-RAM swap and no disk tier, so pressure goes straight to the OOM killer. A swap LV that exists but is not in/etc/fstabdoes not count. Fix: activate disk swap behind a smaller zram — see Fedora → Swap and the reasoning in Disk Strategy → zram. - The killed process is the scapegoat. The OOM killer picks by
oom_score_adj; Electron renderers run at 300, so VS Code is chosen over a browser that is holding five times as much. In the task table above, look forIsolated(Firefox content processes) orchromehelpers summing to many GB across dozens of processes. - Orphaned sessions. Long-lived
claude, language servers or Jupyter kernels in directories that no longer exist still hold their RSS (and swap).ps -eo pid,etime,rss,args --sort=-rss | headandreadlink /proc/<pid>/cwd— a(deleted)suffix means it is safe to close.
Rogue shell injections after tool install¶
Symptom: bootstrap.sh audit reports [rogue] entries.
Fix: Remove the offending lines from the reported files. The
framework's conf.d/10-path.zsh is the single source of truth for
PATH; ad-hoc installer-injected lines duplicate or conflict with it.