pypa/pip · error · PEP723Exception

Failed to parse TOML in

Error message

Failed to parse TOML in {scriptfile!r}

What it means

pip extracted the content of a PEP 723 '# /// script' block but tomllib.loads() raised an exception when parsing it. The block content must be valid TOML. The original exception is chained via 'from exc' for debugging.

Solutions

  1. Copy the TOML from inside the '# /// script' block and validate it with a TOML linter or 'python -c "import tomllib; tomllib.loads(open(\"x\").read())"'
  2. Check for unclosed brackets, missing commas, and mismatched quotes
  3. Ensure the content is stripped of the '# ' comment prefix correctly — each line inside the block must start with '# ' or '#'

Example fix

# before
# /// script
# dependencies = ["requests"
# ///

# after
# /// script
# dependencies = ["requests"]
# ///
Defensive patterns

Strategy: validation

Validate before calling

import re
from pip._internal.utils.compat import tomllib

REGEX = r"(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\s(?P<content>(^#(| .*)$\s)+)^# ///$"

def validate_pep723_toml(filepath: str) -> bool:
    with open(filepath) as f:
        script = f.read()
    matches = [m for m in re.finditer(REGEX, script) if m.group("type") == "script"]
    if not matches:
        return False
    content = "".join(
        line[2:] if line.startswith("# ") else line[1:]
        for line in matches[0].group("content").splitlines(keepends=True)
    )
    try:
        tomllib.loads(content)
        return True
    except Exception:
        return False

Type guard

from pip._internal.utils.compat import tomllib

def is_valid_pep723_toml(content: str) -> bool:
    """Type guard: True if the extracted PEP 723 content is valid TOML."""
    try:
        tomllib.loads(content)
        return True
    except tomllib.TOMLDecodeError:
        return False

Try / catch

from pip._internal.req.pep723 import pep723_metadata, PEP723Exception

try:
    meta = pep723_metadata("script.py")
except PEP723Exception as e:
    if "Failed to parse TOML" in e.msg:
        print("Fix the TOML syntax inside the '# /// script' block")
    else:
        raise

Prevention

When it happens

Trigger: The TOML inside a '# /// script' block has a syntax error such as an unclosed array bracket, a missing value, or a duplicate key. For example: '# dependencies = ["requests"' without the closing bracket.

Common situations: Hand-editing the inline metadata block and introducing a typo. Quote mismatches (mixing single and double). Forgetting a comma in an array. Trailing content after a value.

Understand the failure class

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/da80e8004849ff3b. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_internal/req/pep723.py:35

    with open(scriptfile, encoding="utf8") as f:
        script = f.read()

    name = "script"
    matches = list(
        filter(lambda m: m.group("type") == name, re.finditer(REGEX, script))
    )

    if len(matches) > 1:
        raise PEP723Exception(f"Multiple {name!r} blocks found in {scriptfile!r}")
    elif len(matches) == 1:
        content = "".join(
            line[2:] if line.startswith("# ") else line[1:]
            for line in matches[0].group("content").splitlines(keepends=True)
        )
        try:
            metadata = tomllib.loads(content)
        except Exception as exc:
            raise PEP723Exception(f"Failed to parse TOML in {scriptfile!r}") from exc
    else:
        raise PEP723Exception(
            f"File does not contain {name!r} metadata: {scriptfile!r}"
        )

    return metadata

View on GitHub (pinned to f399c37189)