pypa/pip · error · PipError
Editor Subprocess exited with exit code {e.returncode}
Error message
Editor Subprocess exited with exit code {e.returncode} What it means
Raised by ConfigurationCommand.open_in_editor when the editor subprocess returns a non-zero exit code (subprocess.CalledProcessError). pip wraps the failure into a PipError reporting the editor's return code, because 'pip config edit' shells out via subprocess.check_call('{editor} "{fname}"', shell=True).
Source
Thrown at src/pip/_internal/commands/configuration.py:254
fname = self.configuration.get_file_to_edit()
if fname is None:
raise PipError("Could not determine appropriate file.")
elif '"' in fname:
# This shouldn't happen, unless we see a username like that.
# If that happens, we'd appreciate a pull request fixing this.
raise PipError(
f'Can not open an editor for a file name containing "\n{fname}'
)
try:
subprocess.check_call(f'{editor} "{fname}"', shell=True)
except FileNotFoundError as e:
if not e.filename:
e.filename = editor
raise
except subprocess.CalledProcessError as e:
raise PipError(f"Editor Subprocess exited with exit code {e.returncode}")
def _get_n_args(self, args: list[str], example: str, n: int) -> Any:
"""Helper to make sure the command got the right number of arguments"""
if len(args) != n:
msg = (
f"Got unexpected number of arguments, expected {n}. "
f'(example: "{get_prog()} config {example}")'
)
raise PipError(msg)
if n == 1:
return args[0]
else:
return args
def _save_configuration(self) -> None:
# We successfully ran a modifying command. Need to save the
# configuration.View on GitHub (pinned to d7d0d0a394)
Solutions
- Re-run the edit and ensure the editor exits cleanly (e.g. in vim use :wq not :cq).
- Check the file is writable: 'ls -l <config-file>' and fix permissions.
- Set EDITOR to a reliable terminal editor: export EDITOR=nano or export EDITOR='vim'.
- For GUI editors that fork, configure them to foreground, or edit the file directly.
Example fix
// before # EDITOR='code --wait' returns non-zero in some shells pip config edit // after export EDITOR=vim pip config edit
Defensive patterns
Strategy: try-catch
Validate before calling
import shutil, os
editor = os.environ.get("VISUAL") or os.environ.get("EDITOR") or ""
if editor and not shutil.which(editor.split()[0]):
raise SystemExit(f"EDITOR {editor!r} not found on PATH") Try / catch
# subprocess.run + check returncode yourself instead of relying on pip's wrapper
import subprocess
rc = subprocess.call([editor, fname])
if rc != 0:
print(f"editor exited {rc}; config not saved reliably", file=sys.stderr) Prevention
- Set EDITOR to a terminal editor that exits 0 on normal quit (vim :wq, nano Ctrl+O/X).
- Avoid GUI editors that fork and return immediately with non-zero status.
- Confirm the config file is writable before launching the editor.
When it happens
Trigger: The chosen editor (from --editor, $VISUAL, or $EDITOR) launched but exited non-zero: the user closed it with an error, it failed to save, or it printed an error and quit. Note: a missing editor binary raises FileNotFoundError instead (re-raised), not this error.
Common situations: EDITOR pointing to a GUI editor that forks and returns immediately with a non-zero status; an editor that errors on the file (permissions, read-only); vim/nano exited via :cq (exit code 1); a wrapper script that returns non-zero on success.
Related errors
- Could not determine appropriate file.
- Could not determine editor to use.
- Need exactly one file to operate upon (--user, --site, --glo
- Can not open an editor for a file name containing " {fname}
- Got unexpected number of arguments, expected {n}. (example:
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/b75f28a8cdf86fea.json.
Report an issue: GitHub.