tl;dr
- When
flutter
is not recognized as a command, the application is most likely not part of your$PATH
variable - To fix it, you need to append the
bin
directory of it to your$PATH
variable - On Windows, do it preferably via GUI
- On Linux und MacOS, put the following line in
$HOME/.zshrc
(or.bashrc
respectively):export PATH="$YOUR_FLUTTER_DIR/bin:$PATH"
The flutter
command is needed for every important action related to Flutter, such as:
- Running the app
- Updating the dependencies
- Determining you installation’s status (
flutter doctor
) - …
However, if there is a problem with the executable, you might get the error:
1command not found: flutter
Let’s clarify the root cause of the error, what you need to know about the $PATH
variable and how to debug the issue.
What does the error mean?
The error means a simple thing: your shell (bash
, zsh
or whatever shell you are using) is telling you that it looked into the $PATH
, but could not find an executable named flutter
.
Let’s say you downloaded Flutter and put it in a folder called “flutter” in your home folder ($HOME/flutter
). You need to tell your shell to look right there for the executable file, as it doesn’t know by itself.
Where does the OS look for flutter
?
Whenever you type a command - this can be any token you enter into your shell - the first thing the shell will do is to look inside its $PATH
for an executable with the very name you have entered.
The important part is that there are a bunch of folders that are set by default, but if you want to make a new command available, you have to extend the $PATH
variable by the new directory and thus tell it to look there as well.
Let’s look at how to set the path variable on different operating systems.
Windows
Under Windows, working with a shell is rather unpopular. Instead, most of the time, you work with the GUI of the OS. I will explain both ways, starting with the GUI:
GUI
- Using the keyboard shortcut
Windows Key
+X
you access the Power User Task Menu. - Select the System option.
- Scroll down and click About.
- Click the Advanced System Settings text button at the bottom of Device Specifications.
- Click the Advanced tab, then click the Environment Variables button near the bottom.
- Choose the Path variable in the System Variables area and click the Edit button. There you may add or modify the path lines with the paths you want the OS to access. Separate the paths with a semicolon.
CLI
If you prefer to set such options via the CLI, you can do this with a simple command: setx
.
You need to run this from a privileged CLI.
To do that, right-click the cmd
shortcut (e. g. Windows Key and then enter “cmd”) and select “Run as Administrator”.
If your Flutter directory is C:\Downloads\Flutter
, you need to set it like this:
1setx /M PATH "%PATH%;C:\Downloads\Flutter\bin\flutter"
Using /M
as an option will perform the change of PATH
in HKEY_LOCAL_MACHINE
instead of HKEY_CURRENT_USER
, which makes it a system wide change and not only a user change.
setx
truncates the stored path string to 1024 bytes (which equals to 1024 characters). This can lead to data loss if the path is already about 1024 bytes or longer!
If you are unsure, use echo %PATH%
to read it beforehand.Linux (with zsh
)
On Linux distributions, there is unlike Windows not only one single source of truth. Instead, there is a defined order at which the OS sources files on booting up, that can alter the $PATH
.
Some files are sourced under different circumstances, so it’s good to know, when to modify which one.
The files are sources in the following order:
1. /etc/zshenv
/ $HOME/.zshenv
(Always sourced)
.zshenv
is sourced in any case. If environment variables are set there, then it should be ones that are updated frequently. It’s also used for exported variables that are suppoed to be read by other applications like $EDITOR
, $PAGER
and the one we’re interested in: $PATH
.
Keep in mind that this file is sourced even when zsh
is started to run a single command, also by other programs e. g. make
. You should know what you’re doing as you can break the standard commands.
.zshenv
also allows you to specify a new location for the rest of the zsh
config. You can do this by setting $ZDOTDIR
.
2. /etc/zprofile
/$HOME/.zprofile
(Sourced at login)
Since .zprofile
is used for login shells, it’s usually only sourced once. It’s basically an alternative to .zlogin
(which is sourced two steps after) that should be rather used for variables that are not updated that frequently.
Lines they contain are only executed once, at the beginning of your login session.
If you make changes to this file and want to apply the configuration immediately, you can do this by running a login shell:
1exec zsh --login
3. /etc/zshrc
/ $HOME/.zshrc
(Sourced in interactive shell)
This is probably the file you will change most of the time because it affects your interactive shells. It’s often used for things such as:
- Aliases
- Key bindings
- Output colors
- Shell command history
- Setting the
$PATH
variable
4. /etc/zlogin
/ $HOME/.zlogin
(Sourced at login)
Similar to .zprofile
read at login, but sourced after .zshrc
if the shell is not only login but also interactive.
5. /etc/zlogout
/ $HOME/.zlogout
(Sourced at logout)
Like the name implies, it’s called when logging out within the login shell. Can be used for clearing the terminal.
Conclusion
To solve the issue on Linux, put the following line in $HOME/.zshrc
where $YOUR_FLUTTER_DIR
is the directory where you downloaded Flutter:export PATH="$YOUR_FLUTTER_DIR/bin:$PATH"
.
If you’re working e. g. with bash
, you put it in the respective equivalent (.bashrc
) instead.
MacOS (Catalina and newer)
MacOS behaves quite similar to Linux distributions. However, there are slight differences.
Let’s examine those by having a look at the execution order:
1. /etc/zshenv
/ $HOME/.zshenv
(Always sourced)
Same behavior as the Linux pendant
2. /etc/zprofile
/$HOME/.zprofile
(Sourced at login)
Basically the same behavior as the Linux pendant. But there is a slight difference in the /etc/zprofile
:
Which is the system-wide equivalent of the .zprofile
of the user.
Its content looks like this:
1# System-wide profile for interactive zsh(1) login shells.
2
3# Setup user specific overrides for this in ~/.zprofile. See zshbuiltins(1)
4# and zshoptions(1) for more details.
5
6if [ -x /usr/libexec/path_helper ]; then
7 eval `/usr/libexec/path_helper -s`
8fi
Now what is the path_helper
? Well, let the man
page give us the answer:
"The path_helper utility reads the contents of the files in the directories /etc/paths.d and /etc/manpaths.d and appends their contents to the
PATH
andMANPATH
environment variables respectively."—man
page ofpath_helper
So apparently, this program only concatenates the content of /etc/paths.d
and /etc/manpaths.d
which in my case only contains /Library/Apple/usr/bin
.
3. /etc/zshrc
/ $HOME/.zshrc
(Sourced in interactive shell)
Basically the equivalent of the Linux pendant.
4. /etc/zshrc_Apple_Terminal
(Sourced in interactive shell)
This gives the terminal app of MacOS zsh
support.
5. /etc/zlogin
/ $HOME/.zlogin
(Sourced at login)
Same behavior as the Linux pendant.
6. /etc/zlogout
/ $HOME/.zlogout
(Sourced at logout)
Overview
Here is an overview of the above explanation. The rows in the table represent the order of execution.
system-wide | user | login shell | interactive shell | scripts |
---|---|---|---|---|
/etc/zshenv | $HOME/.zshenv | x | x | x |
/etc/zprofile | $HOME/.zprofile | x | ||
/etc/zshrc | $HOME/.zshrc | x | ||
/etc/zshrc_Apple_Terminal | x | |||
/etc/zlogin | $HOME/.zlogin | x | ||
/etc/zlogout | $HOME/.zlogout | x |
system-wide lists the files that affect all users, users the respective files that only affect the current user.
The overview also describes, which of the files is sourced when opening a login shell, an interactive shell or before a script execution:
Conclusion
Like on Linux, put the following line in $HOME/.zshrc
where $YOUR_FLUTTER_DIR
is the directory where you downloaded Flutter:export PATH="$YOUR_FLUTTER_DIR/bin:$PATH"
.
Debugging the $PATH
If you want to know, what’s currently inside your $PATH
variable, you can just print out its value.
Windows: echo %PATH%
Linux and MacOS: echo $PATH
Putting it all together
Command not found: flutter has simple root cause: flutter as a binary is not in a directory where your operating system looks for it.
In order to make it work, you have to add the location of your flutter binary to the $PATH
variable of your operating system.
On Windows, you can do it via GUI or CLI.
On Linux and MacOS, add or update
1export PATH="$YOUR_FLUTTER_DIR/bin:$PATH"
to your .zshrc
or .bashrc
.
If you’re unfamiliar with editing hidden text files: just enter nano ~/.zshrc
, change the line, press CTRL+X
to close and Y
to override. Re-source the file by entering source ~/.zshrc
.
Comment this 🤌