{"id":"0f7f60951cf9ff5a","repo":"pypa/pip","slug":"can-not-open-an-editor-for-a-file-name-containing","errorCode":null,"errorMessage":"Can not open an editor for a file name containing \"\n{fname}","messagePattern":"Can not open an editor for a file name containing \"\n(.+?)","errorType":"exception","errorClass":"PipError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/commands/configuration.py","lineNumber":243,"sourceCode":"\n    def print_env_var_values(self) -> None:\n        \"\"\"Get key-values pairs present as environment variables\"\"\"\n        write_output(\"%s:\", \"env_var\")\n        with indent_log():\n            for key, value in sorted(self.configuration.get_environ_vars()):\n                env_var = f\"PIP_{key.upper()}\"\n                write_output(\"%s=%r\", env_var, value)\n\n    def open_in_editor(self, options: Values, args: list[str]) -> None:\n        editor = self._determine_editor(options)\n\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}\")'","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/commands/configuration.py#L225-L261","documentation":"Raised by ConfigurationCommand.open_in_editor when the resolved config file path contains a double-quote character. Because the editor is launched via shell with the filename quoted ('{editor} \"{fname}\"'), a quote in the path would break the command and is a shell-injection risk, so pip refuses (configuration.py:240). The comment notes this essentially only happens with an unusual username.","triggerScenarios":"The OS username or HOME path contains a \" character, which then appears in the user config file path (e.g. ~/.config/pip/pip.conf expanded form). get_file_to_edit returns such a path.","commonSituations":"A username containing a quote (extremely rare); a HOME environment variable set to a path with a quote; a misconfigured virtualenv root.","solutions":["Rename the user account / HOME to a path without double-quotes.","Set HOME (or APPDATA on Windows) to a quote-free directory.","Edit the config file manually with your editor instead of 'pip config edit'.","File a pull request as the source comment suggests - pip could pass the path as an argv element instead of via shell."],"exampleFix":"// before\nexport HOME='/home/user\"q'\npip config edit\n// after\nexport HOME='/home/userq'\npip config edit","handlingStrategy":"validation","validationCode":"import os\nhome = os.environ.get(\"HOME\") or os.environ.get(\"USERPROFILE\") or \"\"\nif '\"' in home:\n    raise SystemExit(\"HOME contains a double-quote; pip config edit cannot shell-escape it safely\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep usernames/HOME free of shell-special characters.","Edit the config file directly if your path contains unusual characters."],"tags":["pip","config","cli","shell-injection-guard","filesystem"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}