pypa/pip · error · InstallationError

{editable_req} is not a valid editable requirement. It shoul

Error message

{editable_req} is not a valid editable requirement. It should either be a path to a local project or a VCS URL (beginning with {backends}).

What it means

Raised by parse_editable() when an `-e`/editable requirement string is neither a local file:// path nor a recognized VCS URL. Editable installs require the source to be a locally checked-out project or a VCS checkout URL (git+, hg+, svn+, bzr+); a plain http(s) URL or bare PyPI name is rejected at constructors.py:157.

Source

Thrown at src/pip/_internal/req/constructors.py:159

    """Parses an editable requirement into:
        - a requirement name with environment markers
        - an URL
        - extras
    Accepted requirements:
        - svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir
        - local_path[some_extra]
        - Foobar[extra] @ svn+http://blahblah@rev#subdirectory=subdir ; markers
    """
    try:
        package_name, url, extras = _parse_direct_url_editable(editable_req)
    except ValueError:
        package_name, url, extras = _parse_pip_syntax_editable(editable_req)

    link = Link(url)

    if not link.is_vcs and not link.url.startswith("file:"):
        backends = ", ".join(vcs.all_schemes)
        raise InstallationError(
            f"{editable_req} is not a valid editable requirement. "
            f"It should either be a path to a local project or a VCS URL "
            f"(beginning with {backends})."
        )

    # The project name can be inferred from local file URIs easily.
    if not package_name and not link.url.startswith("file:"):
        raise InstallationError(
            f"Could not detect requirement name for '{editable_req}', "
            "please specify one with your_package_name @ URL"
        )
    return package_name, url, extras


def check_first_requirement_in_file(filename: str) -> None:
    """Check if file is parsable as a requirements file.

    This is heavily based on ``pkg_resources.parse_requirements``, but

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. If installing a local project in development mode, pass the directory path: `pip install -e ./local_project`.
  2. If installing from a VCS, prefix the URL with the VCS scheme, e.g. `pip install -e git+https://github.com/org/repo.git`.
  3. If you just want the released package, drop the `-e` flag: `pip install requests`.
  4. Double-check the path exists and contains pyproject.toml/setup.py before using -e.

Example fix

# before
pip install -e https://github.com/org/repo.git
# after
pip install -e git+https://github.com/org/repo.git
Defensive patterns

Strategy: validation

Validate before calling

import os, re
from pip._internal.vcs import vcs

def looks_like_valid_editable(spec: str) -> bool:
    if os.path.isdir(spec):
        return True
    schemes = tuple(vcs.all_schemes)  # e.g. git+, hg+, svn+, bzr+
    return spec.startswith(schemes) or spec.startswith("file:")

# before pip install -e:
if not looks_like_valid_editable(spec):
    raise ValueError(f"{spec!r} must be a local path or VCS URL")

Type guard

def is_editable_spec(spec: str) -> bool:
    import os
    from pip._internal.vcs import vcs
    return (os.path.isdir(spec)
            or spec.startswith((*vcs.all_schemes, 'file:')))

Try / catch

from pip._internal.exceptions import InstallationError

try:
    ireq = install_req_from_editable(spec)
except InstallationError as e:
    if "is not a valid editable requirement" in str(e):
        # fall back to a non-editable install or prompt user
        ...
    raise

Prevention

When it happens

Trigger: Running `pip install -e https://example.com/foo` (plain https, not VCS), `pip install -e requests` (a package name, not a path), or `pip install -e ./missing_dir` where the path does not resolve to a file:// URL. The check is `not link.is_vcs and not link.url.startswith('file:')`.

Common situations: Confusing a regular install with an editable one. Forgetting the `git+` prefix on a GitHub URL. Typing a package name instead of a local path. Pointing -e at a URL that 404s into a non-file scheme.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/7d1114fff6610257.json. Report an issue: GitHub.