Troubleshooting¶
If syntax checking does not work as expected there are a number of steps that you can follow to isolate and maybe fix the problem.
Common issues¶
First check whether your issue is one of the common setup issues and problems.
Flycheck can’t find any programs in GUI Emacs on macOS¶
Try to install and configure exec-path-from-shell to make a GUI Emacs inherit
the $PATH environment variable from your shell configuration.
The issue is that due to the special way macOS starts GUI programs a GUI Emacs
does not inherit the environment variables from the shell configuration so Emacs
will lack some important entries in $PATH, most notably /usr/local/bin/
where Homebrew, NPM and many other package managers put binaries in.
The exec-path-from-shell works around this issue by extracting environment variables from a shell session and inject them into the environment of the running Emacs instance.
Flycheck says it “cannot read” a syntax checker’s output¶
The message looks like this:
Flycheck: cannot read python-flake8's output, so it may be misconfigured;
C-c ! v shows what it printed
It means the tool ran, exited with a failure, and printed nothing Flycheck could turn into errors. Press C-c ! v: the verification buffer leads with whatever the checker actually printed, which is nearly always the answer.
By far the most common cause is the tool being missing from, or broken in, the
environment Emacs is using. A python-flake8 pointed at an interpreter
without flake8’s dependencies prints a Python traceback ending in
ModuleNotFoundError; a linter whose plugin failed to load says so. Neither
is a Flycheck problem. On macOS this is often the $PATH problem described
above, and if you use direnv or
virtualenvs, check that the tool Emacs finds is the project’s and not a global
one.
The next most common cause is a version mismatch: newer Flycheck releases may pass flags older tools do not understand, or parse an output format they do not produce yet. Update the tool before anything else.
If the tool is current and its output looks like something Flycheck ought to have understood, that is a flaw in the checker definition, so please report a bug and include what the verification buffer showed.
A syntax checker disabled itself¶
Flycheck: python-flake8 disabled itself in this buffer
(ModuleNotFoundError: No module named 'pycodestyle'); C-u C-c ! x re-enables it
Some checkers recognise the exit status their tool uses to say it could not run at all, as opposed to reporting findings, and step aside rather than failing the same way on every check. The reason in parentheses comes from the tool.
Fix whatever it names and the checker works again. To bring it back without restarting Emacs, use C-u C-c ! x.
This is also how a linter with no configuration file behaves. A stylelint with nothing to lint by, for instance, disables itself instead of reporting an error on every check.
Flycheck does nothing at all in a buffer¶
Look at the mode line first; see Start from the mode line
below. FlyC- means no syntax checker applies to the buffer, which usually
means the tool is not installed or the buffer’s major mode has no checker.
C-c ! v lists every checker that could apply and why each one is or is
not usable.
Start from the mode line¶
Flycheck says what state it is in next to the mode name, and every state that is not a set of error counts is a single character:
|
Not checked yet |
|
No syntax checker for this buffer |
|
A check is running |
|
Finished: two errors, one warning, no infos |
|
The syntax checker could not be run |
|
The check was interrupted |
|
The checker returned something Flycheck could not read |
Every one of these except the counts explains itself if you hover it, and clicking it runs flycheck-verify-setup on the buffer, which is where the answer usually is. Clicking the error counts opens the error list instead.
A trailing + on the counts means errors were suppressed because the check
produced more than flycheck-checker-error-threshold.
Verify your setup¶
If your issue is none of the aforementioned common issues the first step is to let Flycheck check your setup:
- C-c ! v¶
- M-x flycheck-verify-setup¶
Show a verification buffer with information about your
Flycheck Modesetup for the current buffer.The buffer contains all syntax checkers available for the current buffer and tells you whether Flycheck would use each one and what reasons would prevent Flycheck from using a checker. It also includes information about your Flycheck and Emacs version and your operating system.
The following image shows a verification buffer:
The buffer groups the checkers by what will actually happen to them: the one that runs, the ones that would run if you selected them, and the ones that cannot run as things stand. Click a checker’s name for its docstring.
Green items indicate good configuration. In the screenshot
python-ruffandpython-pycompilewere both found.Orange items indicate a potential misconfiguration. The screenshot shows that no configuration file was found for
python-ruff, which is perfectly fine if the project has none, but not so good if you meant Flycheck to use one. The section Configuration files has more information about configuration files.Red items indicate bad configuration. Neither
python-flake8norpython-pylintwas found in the screenshot, so neither can run in that buffer, and each says it disabled itself rather than failing on every check. C-u C-c ! x brings a disabled checker back once you have installed it.
A checker that is registered nowhere is called out separately, under a heading
telling you to add it to flycheck-checkers.
The verification buffer also shows:
What the last failed check reported, at the very top, when a checker could not be run or printed something Flycheck could not read. This is the tool’s own output, and it is usually the whole answer.
Whether each checker is disabled (manually via
C-c ! x, automatically due to too many errors, or because the checker stepped aside). You can re-enable disabled checkers withC-u C-c ! x.The selected checker for the current buffer (set via
C-c ! s), if any.For a buffer backed by a language server, how many diagnostics its server pushed and how many of those changed anything. A server pushing many times a second is a very different problem from a checker that is simply slow.
Your Flycheck version, Emacs version and operating system, which is useful information when reporting bugs.
Tip
When reporting a bug, include the output of
C-c ! v in your report. It gives maintainers a quick overview of your
setup.
LSP diagnostics¶
Diagnostics that come from a language server, through either
flycheck-eglot-mode or flycheck-lsp-mode, fail differently from command
checkers: there is no exit status and no output to read, just a server that may
or may not be saying anything. See Check buffers for how the
two integrations work.
Nothing appears in an Eglot buffer. Eglot renders its diagnostics through
Flymake by default and provides no Flycheck backend, so Flycheck shows nothing
until you bridge them with global-flycheck-eglot-mode. Check the mode is
actually on in the buffer; it only activates where Eglot manages one.
Nothing appears with the native checker. flycheck-lsp-mode does nothing
in a buffer whose major mode has no entry in flycheck-lsp-servers, or whose
server program is not installed. The verification buffer says which of the two
it is. A server that fails its initialize handshake is torn down and
retried on the next check, so a buffer that never produces diagnostics may be
failing to start the server at all.
Only one of two servers reports. Both bridges chain onward only when their
exclusive option is nil; see Eglot and a second server together.
Emacs slows down or stutters. A language server publishes diagnostics
whenever it likes, and some publish continuously while they index or build a
project. Each push that carries something new re-runs the check that publishes
it. Run C-c ! v while it is happening and look at the push counts: a
server pushing many times a second is the problem, not the checks themselves.
Turning global-flycheck-annotate-mode off tells you whether the cost is in the
number of checks or in what each one draws.
For the underlying protocol traffic, Eglot keeps its own event log. Set
eglot-events-buffer-config (eglot-events-buffer-size on Emacs 29 and
earlier), reproduce, and read the *EGLOT … events* buffer.
Debug syntax checkers¶
If a syntax checker fails although it successfully verified you need to take a closer look. Flycheck provides you with a command that lets you run a single syntax checker just the way Flycheck would run it:
- C-c ! C-c¶
- M-x flycheck-compile¶
Prompt for a syntax checker and run it as a shell command, showing the whole output in a separate buffer.
Note
This only works for command checkers. A checker backed by a language server has no command line to reproduce; see LSP diagnostics above.
The output of this command can provide you helpful clues about what’s going on. It also helps to compare the output of the command in Emacs with what happens if you run the same command in a terminal.
If all else fails…¶
…please do ask for help. You can ask questions on Stack Exchange or open an issue on GitHub, and we try to help you as fast and as well as possible.