Skip to content

Troubleshooting

Common problems and how to resolve them safely. Inspect first, change second — every section starts with read-only checks before any fix. Destructive or modifying steps are marked.

Never use stow --adopt

--adopt silently overwrites your existing files with the repository version and cannot be undone without the original. It is forbidden in this repository. Resolve conflicts manually instead.

Start here: task doctor

Before working through the cases below, run the health check — it is read-only, needs no network, and usually names the problem outright:

task doctor

Because every managed layer is guarded, a broken setup starts a shell exactly as cleanly as a correct one. doctor asserts the positives instead of inferring health from the absence of errors.

Stow reports a conflict

A real file already exists at the link target. Inspect it:

ls -la ~/.config/<package>/

Resolve by moving the existing file aside, then re-running the dry-run:

⚠️ MANUAL STEP — moves your existing file; review first

mv ~/.config/<package>/<file> ~/.config/<package>/<file>.bak
stow --dir=stow/common --target="$HOME" --simulate <package>

Only apply once the dry-run is clean. Full detail in the GNU Stow Workflow.

If ~/.config/<package> or another managed config directory such as ~/.codex is itself a symlink (leading l), Stow folded the directory. Several packages require --no-folding (zsh, alacritty, herdr, codex, git, bat, btop, eza, claude, nvim).

Check:

ls -ld ~/.config/<package>    # leading "l" = folded symlink

Fix — unstow, recreate as a real directory, re-stow with --no-folding:

⚠️ MANUAL STEP — review each command before running

stow --dir=stow/common --target="$HOME" --delete <package>
mkdir -p ~/.config/<package>
stow --dir=stow/common --target="$HOME" --no-folding <package>
test ! -L "$HOME/.config/<package>" && echo "OK: real directory"

Confirm a symlink resolves back into the repository:

readlink ~/.config/<package>/<file>

If it points somewhere unexpected or is dangling, unstow and re-stow the package (dry-run first).

Missing dependencies / command not found

Most tools are optional and guarded — the shell starts cleanly without them, and an alias simply won't exist. Check what's present:

task check            # core: stow, git, task
task deps:check:zsh   # shell tools
task deps:check:nvim  # editor tools

Install what's missing using the commands on the Shell Dependencies and Installation pages. Nothing installs automatically.

Shell not loading the managed config

The zsh package never touches ~/.zshrc; you add one guarded include block yourself. Preview what the bootstrap would add:

task zsh:bootstrap:dry-run

Apply it (idempotent, creates a timestamped backup):

⚠️ MANUAL STEP — review the dry-run output first

task zsh:bootstrap

Then start a new shell. See Shell.

A completion only works after exec zsh

Symptom: in a newly opened terminal, herdr <Tab> or task <Tab> completes filenames instead of arguments. Typing exec zsh fixes it — until the next new window.

The tool is not on PATH yet when its layer loads. Every optional layer opens with command -v <tool> >/dev/null 2>&1 || return, and a failed guard does not retry — the layer returns and registers nothing. compinit behaves the same way with fpath: it runs once, so a completion directory added afterwards is never scanned. exec zsh seems to cure it only because PATH and FPATH are exported and the replacement shell inherits them.

The usual cause is PATH setup sitting in ~/.config/zsh/local.zsh, which is sourced last — after every guard and after compinit. Check, in a clean environment (0 means never registered):

env -i HOME="$HOME" TERM=xterm PATH=/usr/local/sbin:/usr/local/bin:/usr/bin zsh -ic \
  'print -r -- "herdr=${+_comps[herdr]} task=${+_comps[task]}"'

Fix: move that setup — including any brew shellenv call — into ~/.zshrc above the managed block, and drop any hand re-init lines it left behind (tools.zsh already initialises zoxide, in its correct after-prompt position). See Shell.

Git config not applied

Confirm the managed includes are wired into ~/.gitconfig:

git config --global --get-all include.path   # expect the two managed paths
git config --global core.excludesfile        # expect ~/.config/git/ignore

If empty, run the bootstrap (preview first):

task git:bootstrap:dry-run

⚠️ MANUAL STEP — review the dry-run output first

task git:bootstrap

See Git.

Icons or fonts not rendering

OS glyphs, git symbols, and eza icons need a Nerd Font in your terminal. If the Oh My Posh prompt renders its glyphs, the Claude status line and eza icons will too. Set your terminal font to a Nerd Font and restart it.

bat theme not applied

bat reads themes from a compiled cache — build it once after stowing:

bat cache --build
bat --list-themes | grep "Catppuccin Macchiato"

eza colors look default

Usually EZA_CONFIG_DIR points away from ~/.config/eza. Check:

echo "$EZA_CONFIG_DIR"
readlink ~/.config/eza/theme.yml

If the variable is set, eza reads theme.yml from there instead — unset it or point it at ~/.config/eza.

MkDocs local preview issues

To preview this site locally without installing anything, serve it via Docker from the repository root:

docker run --rm -it -p 8000:8000 -v "$PWD":/docs squidfunk/mkdocs-material serve --dev-addr=0.0.0.0:8000

Open http://localhost:8000. The --dev-addr=0.0.0.0:8000 binding is required so the container is reachable from the host.