{"id":"b75f28a8cdf86fea","repo":"pypa/pip","slug":"editor-subprocess-exited-with-exit-code-e-returnc","errorCode":null,"errorMessage":"Editor Subprocess exited with exit code {e.returncode}","messagePattern":"Editor Subprocess exited with exit code (.+?)","errorType":"exception","errorClass":"PipError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/commands/configuration.py","lineNumber":254,"sourceCode":"\n        fname = self.configuration.get_file_to_edit()\n        if fname is None:\n            raise PipError(\"Could not determine appropriate file.\")\n        elif '\"' in fname:\n            # This shouldn't happen, unless we see a username like that.\n            # If that happens, we'd appreciate a pull request fixing this.\n            raise PipError(\n                f'Can not open an editor for a file name containing \"\\n{fname}'\n            )\n\n        try:\n            subprocess.check_call(f'{editor} \"{fname}\"', shell=True)\n        except FileNotFoundError as e:\n            if not e.filename:\n                e.filename = editor\n            raise\n        except subprocess.CalledProcessError as e:\n            raise PipError(f\"Editor Subprocess exited with exit code {e.returncode}\")\n\n    def _get_n_args(self, args: list[str], example: str, n: int) -> Any:\n        \"\"\"Helper to make sure the command got the right number of arguments\"\"\"\n        if len(args) != n:\n            msg = (\n                f\"Got unexpected number of arguments, expected {n}. \"\n                f'(example: \"{get_prog()} config {example}\")'\n            )\n            raise PipError(msg)\n\n        if n == 1:\n            return args[0]\n        else:\n            return args\n\n    def _save_configuration(self) -> None:\n        # We successfully ran a modifying command. Need to save the\n        # configuration.","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/commands/configuration.py#L236-L272","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n# EDITOR='code --wait' returns non-zero in some shells\npip config edit\n// after\nexport EDITOR=vim\npip config edit","handlingStrategy":"try-catch","validationCode":"import shutil, os\neditor = os.environ.get(\"VISUAL\") or os.environ.get(\"EDITOR\") or \"\"\nif editor and not shutil.which(editor.split()[0]):\n    raise SystemExit(f\"EDITOR {editor!r} not found on PATH\")","typeGuard":null,"tryCatchPattern":"# subprocess.run + check returncode yourself instead of relying on pip's wrapper\nimport subprocess\nrc = subprocess.call([editor, fname])\nif rc != 0:\n    print(f\"editor exited {rc}; config not saved reliably\", file=sys.stderr)","preventionTips":["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."],"tags":["pip","config","cli","subprocess","editor","environment"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}