Troubleshooting
This section covers common issues, their solutions, and how to safely revert changes or uninstall the configuration entirely.
Uninstalling and Reverting to Backup
Section titled “Uninstalling and Reverting to Backup”The installation step backs up any existing config to ~/.config/fish.bak.
To revert:
rm -rf ~/.config/fishmv ~/.config/fish.bak ~/.config/fishIf no backup exists, remove the directory and let Fish regenerate a default config on next launch:
rm -rf ~/.config/fishfish -c 'fish_config theme choose default 2>/dev/null; or fish_config theme choose "fish default"'fish 4.3 renamed its default theme from fish default to default; the
command tries the new name first and falls back to the old one.
Clean up files generated outside the config directory:
rm -f ~/.local/bin/paru ~/.local/bin/yay # AUR log wrappersrm -f ~/.local/share/man/man1/fish-config.1 # man page symlinkrm -f ~/.config/fish/.logging_disabled # C5 sentinelErase universal variables set by this config:
for v in (set -Un | string match '__fish_config*') set -Ue $vendfor v in __done_min_cmd_duration __done_notification_urgency_level set -Ue $vendfor v in (set -Un | string match 'sponge_*') set -Ue $vendThe ~/.terminal_history/ log directory contains your session logs. Remove
it only if you do not want to keep them.
Fish Version Requirement
Section titled “Fish Version Requirement”This config requires Fish 4.x or newer. Check your version:
fish --versionRun fish-deps to see a status report — an outdated Fish shows ⚠ with an
upgrade message.
On an older Fish, an interactive shell prints a one-time warning on stderr at startup naming the version it found and pointing back to this section. It is a warning only: the rest of the config still loads, and the features that need Fish 4.x may fail with confusing errors until you upgrade.
Upgrading Fish by distribution:
pacman -S fish # or paru -S fishsudo apt-add-repository ppa:fish-shell/release-4sudo apt update && sudo apt install fishsudo dnf install fishbrew install fishFor other systems or building from source, see https://fishshell.com.
Enable or Disable Session Logging
Section titled “Enable or Disable Session Logging”Session logging is opt-in: it is off until you turn it on. To enable all
logging and capture (scrollback, tmux/zellij pane logs, AUR helper wrappers,
Kitty watcher):
set -U __fish_config_op_logging onOr toggle it interactively: run config-settings and flip the Logging row.
Disable it again — either an explicit falsy value or erasing the variable returns you to the default off state:
set -U __fish_config_op_logging offset -Ue __fish_config_op_loggingThis takes effect immediately in all running shells — no restart needed. The sentinel file, wrapper removal, and pipe-pane teardown happen automatically.
See C5 — Logging and Capture for the full component breakdown.
Change or Disable the Greeting
Section titled “Change or Disable the Greeting”This config suppresses the distro greeting (e.g. CachyOS fastfetch) by
default. To let the distro greeting through:
set -U __fish_config_op_greeting offTo set a custom greeting, define fish_greeting in your local.fish:
function fish_greeting echo "Hello, world!"endThe first-run welcome banner runs exactly once. To re-trigger it (e.g. for testing):
set -Ue __fish_config_first_run_completeIf the Fisher/plugin bootstrap failed (offline first run), it is retried automatically on a later start, at most once a day; see Fisher Plugins. To retry on the next start instead of waiting, run:
set -U __fish_config_bootstrap_pending 0See C6 — Greeting and First-Run UI for details.
Secrets and Machine-Local Configuration
Section titled “Secrets and Machine-Local Configuration”Machine-specific config goes in $__fish_user_dots_path/local.fish (defaults
to ~/.config/.user-dots/fish/local.fish). Secrets go in secrets.fish in
the same directory.
If local.fish is not loading, verify the path:
echo $__fish_user_dots_pathtest -f "$__fish_user_dots_path/local.fish"; and echo exists; or echo missingChange the path via variable or TUI:
set -U __fish_user_dots_path /new/path/to/dots/fishOr run config-settings, navigate to the Paths page, and edit “Dots path”.
The user-dots convenience symlink in the config directory tracks this path.
Disable it with:
set -U __fish_user_dots_symlink falseSee Personalization for the full local.fish / secrets.fish
layout.
Tool Init Does Nothing (Return Sentinel)
Section titled “Tool Init Does Nothing (Return Sentinel)”Symptom: you ran a tool’s setup command (e.g.
starship init fish >> ~/.config/fish/config.fish) and nothing changed.
Cause: config.fish ends with a return guard. Any lines appended after it
are never executed.
Fix: create a dedicated conf.d/ file instead of appending to config.fish:
mytool init fish | sourceAll existing integrations (starship, zoxide, direnv) already have conf.d/
files. See Return Sentinel for background.
Slow Startup, or a Tool Init That Looks Stale
Section titled “Slow Startup, or a Tool Init That Looks Stale”Startup work is kept small on purpose, and the generated init scripts of
fzf (fzf --fish) and direnv (direnv hook fish) are cached rather than
regenerated by forking the tool in every new shell. The cache lives in
$XDG_CACHE_HOME/fish-config/init/ (default ~/.cache/fish-config/init/) and
is keyed on the tool binary’s resolved path and modification time, the command
line and the fish version, so installing, upgrading or rebuilding the tool
regenerates the entry on the next start. Anything unexpected (unreadable or
truncated entry, failing tool, unwritable directory) falls back to running the
tool live, exactly as before.
If key bindings or the direnv hook ever look out of date, drop the cache; it
is rebuilt on the next start:
__fish_init_cache --clearTo turn the cache off for good:
set -U __fish_config_init_cache offTo see where startup time goes:
fish --profile-startup=/tmp/startup.txt -i -c exitsort -rn /tmp/startup.txt | head -20The repository’s own test run also times a start of the config and prints a warning if it is over budget; see Section 15, Testing.
Missing Dependencies
Section titled “Missing Dependencies”Run fish-deps (defaults to fish-deps status) to see what is installed
and what is missing. Common symptoms and their missing tools:
| Symptom | Missing tool |
|---|---|
ls output has no icons or colors |
eza (or lsd) |
cd does not remember directories |
zoxide |
cat shows no syntax highlighting |
bat |
fzf keybindings do nothing |
fzf |
Starship prompt not appearing |
starship |
Install missing dependencies interactively:
fish-deps installEach prompt reads [Y/n/q]: q, Ctrl+C or Ctrl+D stops the whole run rather
than just the current step. If an install fails, the cause is usually one of:
| Message | Cause and fix |
|---|---|
linker cc not found |
No C compiler. fish-deps offers build-essential / base-devel / gcc; install it and re-run. |
rustup could not choose a version of cargo |
rustup has no default toolchain. Run: rustup default stable |
Unable to locate package ov |
Not packaged for apt. fish-deps offers Go and go install instead. |
unzip is required |
Install unzip and re-run. |
cannot find lms in the crate root |
An unlocked cargo install picked newer dependencies. fish-deps passes --locked; for a manual install, do the same. |
Or install everything missing and update what is installed:
fish-deps syncSee Dependency Catalog for the full list grouped by tier (required, integrations, recommended).
Vi Mode Keybindings
Section titled “Vi Mode Keybindings”This config enables Vi mode by default (via C3 overrides), replacing the
standard Emacs-style bindings. If Vi mode interferes with your workflow,
override it in local.fish (See Personalization):
fish_default_key_bindingsThis restores Emacs-style bindings without disabling the rest of C3
(bang-bang, autopair, starship prompt, pager settings, etc.).
To disable the entire C3 category (Vi mode and all other key/environment overrides):
set -U __fish_config_op_overrides offSee C3 — Key and Environment Overrides for the full list of what C3 controls.
What’s with the C1-C6 stuff?
Section titled “What’s with the C1-C6 stuff?”This configuration groups its opinionated behaviors into six categories (C1–C6), allowing you to selectively disable features that conflict with your workflow. The Category numbers are used as shorthand when referencing these. Disabling all of them leaves you with a “Minimal Mode” shell that only manages basic features like XDG variables, and your local.fish overrides.
| Category | Description |
|---|---|
C1 |
Command Shadows — Wraps destructive commands (rm, cp) to be safe by default |
C2 |
Startup Side-Effects — Bootstraps Fisher, generates wrappers, auto-activates venvs |
C3 |
[Overrides](/08-components-reference/03-c3-key-and-environment-overrides/) — Overrides cd, sets Vi mode, binds <CR> to smart_enter |
C4 |
Integrations — Kitty/Wezterm integrations, starship hooks, fzf theme |
C5 |
Logging and Capture — Session logs, command duration |
C6 |
Greeting & First-Run UI — Custom startup banner |
Disable all opinionated features at once (Minimal Mode):
set -U __fish_config_opinionated 0Disable a single category:
set -U __fish_config_op_aliases off # C1set -U __fish_config_op_autoexec off # C2set -U __fish_config_op_overrides off # C3set -U __fish_config_op_integrations off # C4set -U __fish_config_op_logging off # C5 (already off by default)set -U __fish_config_op_greeting off # C6Keep one category active under a master disable:
set -U __fish_config_opinionated 0set -U __fish_config_op_aliases 1 # only C1 stays onRe-enable everything:
set -Ue __fish_config_opinionatedEach category can also have several sub-categories (e.g.
__fish_config_op_aliases_filesystem) that can be checked, disabled, or
reset the same way — set -U __fish_config_op_<category>_<subcategory> off
and set -Ue __fish_config_op_<category>_<subcategory> work identically to
the category-level recipes above, just one level more granular. See
Components Reference for the full list.
For an interactive alternative to setting these variables by hand, run config-settings.