I am using fish as my shell in Debian and recently (after some upgrade) whenever I try to use command completion I have:

set: No such file or directory
set: Could not add component /usr/lib/x86_64-linux-gnu/libfm to PATH.
set: No such file or directory

Running this:

echo $PATH 

Gives me this:

/usr/lib/x86_64-linux-gnu/libfm /usr/local/bin /usr/bin /bin /usr/local/games /usr/games

In my system there is no /usr/lib/x86_64-linux-gnu/libfm, so I understand why fish is complaining, but I cannot find how to remove this path from my $PATH variable.

Does anyone know how can I do this?

  • grep -R /usr/lib/x86_64-linux-gnu/libfm ~/.config/fish /usr/share/fish ?? Jul 2, 2014 at 16:10
  • $grep -R /usr/lib/x86_64-linux-gnu/libfm ~/.config/fish /usr/share/fish /home/superuser/.config/fish/fish_history:grep -R /usr/lib/x86_64-linux-gnu/libfm ~/.config/fish /usr/share/fish
    – tomekK
    Jul 3, 2014 at 6:16

4 Answers 4


The 'fish' way of setting the $PATH variable is to actually use set --universal fish_user_paths $fish_user_paths /new/path/here. Then $fish_user_paths is actually prepended to the $PATH variable when a new session starts. The $PATH documentation doesn't currently tell you how to delete it though.

In fish every variable is actually a list (array), and you can conveniently access each item directly by using an index/indice. echo $fish_user_paths will print out a space delimited version of every item in the list, make the spaces newline with the translate function echo $fish_user_paths | tr " " "\n" and then put line numbers on it with the number lines function, echo $fish_user_paths | tr " " "\n" | nl. Then delete it with set --erase --universal fish_user_paths[5]. You must use --universal or it will not work in any new sessions.

If someone has the time, please submit a PR to the repo with this example. I opened an issue here.


  1. echo $fish_user_paths | tr " " "\n" | nl // get the number of the one you want to delete, e.g. the 5th one
  2. set --erase --universal fish_user_paths[5] // erase the 5th path universally so it persists in new sessions
  • 2
    Why is this so arcane? Shouldn't this be a build in feature and added to the documentation so that people doesn't have to Google and end up here? Oh well.. Jan 30, 2018 at 10:12
  • I think if we take @clozach's answer here superuser.com/a/1212305/30982, which is the addpaths() and removepath() function, and open a PR then that would be the first step to getting it added. Most of the maintainers are pretty good to work with, one seems grumpy to me, but overall I think we would have a good chance. So that is our next step. Oct 10, 2018 at 16:13
  • echo $fish_user_paths doesn't return anything, but echo $PATH returns some stuff. Jul 28, 2021 at 16:46
  • What does echo $SHELL return? It should return /usr/bin/fish or something like that. My suspicion is that it is a different shell. If it is fish, then what is fish --version? Jul 29, 2021 at 0:05
  • 1
    This set --erase --universal fish_user_paths[4] doesn't work for me in v3.3.1 for some reson. No errors, but the path is not being deleted from the list.
    – demisx
    Aug 2, 2021 at 16:16

As Elijah says, best practice is to modify the fish_user_paths rather than the global PATH. To avoid ever having to Google this again…

  1. Create a couple of functions that only modify fish_user_paths
  2. Make both functions autoloading

To add to user paths:

function addpaths
    contains -- $argv $fish_user_paths
       or set -U fish_user_paths $fish_user_paths $argv
    echo "Updated PATH: $PATH"

To remove a user path if it exists (partial credit to this):

function removepath
    if set -l index (contains -i $argv[1] $PATH)
        set --erase --universal fish_user_paths[$index]
        echo "Updated PATH: $PATH"
        echo "$argv[1] not found in PATH: $PATH"

And of course, to make them autoloading:

funcsave addpaths; funcsave removepath

Example Usage:

> addpaths /etc /usr/libexec
Modifying PATH: /usr/local/bin /usr/bin /bin /usr/sbin /sbin
Updated PATH: /etc /usr/libexec /usr/local/bin /usr/bin /bin /usr/sbin /sbin

> removepath /usr/libexec
Modifying PATH: /etc /usr/libexec /usr/local/bin /usr/bin /bin /usr/sbin /sbin
Updated PATH: /etc /usr/local/bin /usr/bin /bin /usr/sbin /sbin
  • Note: I've just discovered that this approach won't remove a path added through some other mechanism; Some dot-file cleanup may be in order if you find a path coming back each time you open a new terminal session.
    – clozach
    Aug 29, 2017 at 19:51
  • This is great, just added to my local! Nov 29, 2017 at 0:07
  • This is not working for me. It just prints the back to me, thats all. Jul 28, 2021 at 16:45
  • A better solution, added in a more recent version of fish, is to use the fish_add_path command. fishshell.com/docs/current/cmds/fish_add_path.html
    – m0j0
    Aug 4, 2021 at 18:41

This should erase paths 6 through the last path:

set -e PATH[6..-1]

The -e flag is erase. See help set.

  • this will only work for the current session
    – Daniel
    Nov 4, 2019 at 12:36

Reset fish_user_paths withtout the path you don't want anymore:

 $ set -U fish_user_paths /usr/local/bin /usr/bin /bin /usr/local/games /usr/game

More info: https://fishshell.com/docs/current/tutorial.html#tut_path

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.