What each error actually means, why it happens, and the fastest fix. Findings (HIGH/MEDIUM/LOW dead-code reports) aren't errors — this page is about things that stop PragyaLint from running at all, or make it behave unexpectedly.
pragyalint --version first.
If that fails, it's an installation problem (see below). If it succeeds
but scanning fails, it's a project-level problem — jump to
parse errors or config errors.
pip install put the pragyalint executable
somewhere your shell's PATH doesn't include — almost
always because it was installed with --user, inside a
deactivated virtualenv, or via a Python that isn't the one on your
PATH.
# Confirm it's actually installed and find where
python3 -m pip show pragyalint
python3 -m pip show -f pragyalint | grep pragyalint
# Simplest fix: run it as a module instead of relying on PATH
python3 -m pragyalint # Linux/macOS
py -m pragyalint # Windows (py launcher)
# Or install with pipx, which manages PATH for you
pipx install pragyalint
pragyalint --version
If you installed with pip install --user, add your
user base's bin directory to PATH — on Linux/macOS
that's usually ~/.local/bin:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
On Windows, pip install --user puts the executable in
%APPDATA%\Python\Scripts. Add it to your user
PATH and restart the terminal:
setx PATH "%APPDATA%\Python\Scripts;%PATH%"
This is the Node.js-style version of the same "not found" problem
above — you'll see it in VS Code output panels, pre-commit logs,
or any tool that shells out to pragyalint as a
subprocess (rather than a shell you typed into directly). It means
the process trying to launch PragyaLint couldn't resolve it on its
own PATH, which is not always the same
PATH your terminal uses — GUI apps on macOS
in particular often see a minimal system PATH.
which pragyalint (or where pragyalint
on Windows) and paste that absolute path into the tool's config.
pragyalint.binaryPath in your settings, or install
inside the same virtualenv VS Code's Python interpreter is using.
language: python hook form
so pre-commit manages its own isolated install rather than
shelling out to a system PATH lookup — see
CI / automation.
You installed into one Python environment and are running a different one — usually a system Python vs. a virtualenv/conda env mismatch. Confirm which interpreter you're actually using:
python3 -c "import sys; print(sys.executable)" # Linux/macOS
py -c "import sys; print(sys.executable)" # Windows
python3 -m pip show pragyalint # run with the SAME python3
If they don't match the environment you activated, reinstall with
that exact interpreter: /path/to/venv/bin/python -m pip
install pragyalint.
PragyaLint parses every file with the standard-library
ast module using your currently-running
Python's grammar. Two common causes:
The file uses syntax newer than the Python interpreter running
PragyaLint (e.g. a match statement parsed under
Python 3.9). Run PragyaLint with the same Python version your
project targets: python3.12 -m pragyalint (Windows:
py -3.12 -m pragyalint).
Templated files (Jinja-flavored .py, generated
stubs) aren't valid standalone Python. Exclude them:
pragyalint --ignore "**/*.generated.py" --ignore "templates/**"
A parse error on one file never stops the whole scan — PragyaLint reports it as a finding on that file and continues with the rest of your project.
A source file isn't UTF-8 (common with files edited on Windows
in an editor that defaulted to a different codepage, or a binary
file with a .py extension by mistake). Re-save the
file as UTF-8, or exclude it with --ignore if it's
not meant to be scanned.
--confidence and --fail-on only accept
high, medium, or low
(optionally with a trailing +, e.g.
medium+ to mean "medium and everything stricter").
Check for a typo or a stray value pulled from
pyproject.toml.
PragyaLint reads config from [tool.pragyalint] in
pyproject.toml, or a standalone
pragyalint.toml/pragyalint.json at the
project root. It doesn't merge both — the standalone file wins if
present. See the full precedence order on the
Configuration page.
--fixThree independent gates all have to pass for a deletion to happen:
--fix alone only applies HIGH-confidence findings.
Pass --confidence medium+ or --confidence all
to include MEDIUM/LOW findings too.
If PragyaLint sees getattr(), exec,
eval, or globals()/locals()
anywhere in your project, it refuses to delete definitions
project-wide unless you pass --force. This is
intentional — see Dynamic dispatch.
__all__
Exports listed in __all__, and top-level definitions
in entry files (including test files), aren't deleted by default
even at low confidence — they're treated as the public surface.
Run with --dry-run to see exactly which gate is blocking a given finding before deciding whether to override it.
| Code | Meaning |
|---|---|
0 | Scan completed; no finding met the --fail-on threshold (default: never fails on findings alone). |
1 | At least one finding met or exceeded --fail-on. This is the code CI should watch for. |
2 | Usage error — bad flags, invalid config value, or a root directory that doesn't exist. |
Run with the full traceback and open an issue with it attached — that turns a guess into a two-minute fix on our end.
pragyalint --root-dir . --verbose 2> pragyalint-debug.log
cat pragyalint-debug.log
Open an issue at
github.com/Sanskriti-Studios/PragyaLint/issues
with the log, your OS, and python3 --version.