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
- 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())"'
- Check for unclosed brackets, missing commas, and mismatched quotes
- 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
- Validate TOML inside PEP 723 blocks with a TOML linter before running
- Check for unclosed arrays and missing commas after editing dependency lists
- Each line inside the block must start with '# ' or '#'
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Multiple blocks found in
- Error parsing
- File does not contain
- Configuration file could not be loaded.\n
- Could not split options
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)