{"record":{"id":"5de8e2668b112dc7","repo":"pypa/pip","slug":"multiple-name-r-blocks-found-in-scriptfile-r","errorCode":null,"errorMessage":"Multiple {name!r} blocks found in {scriptfile!r}","messagePattern":"Multiple (.+?) blocks found in (.+?)","errorType":"validation","errorClass":"PEP723Exception","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/req/pep723.py","lineNumber":26,"sourceCode":"\nclass PEP723Exception(ValueError):\n    \"\"\"Raised to indicate a problem when parsing PEP 723 metadata from a script\"\"\"\n\n    def __init__(self, msg: str) -> None:\n        self.msg = msg\n\n\ndef pep723_metadata(scriptfile: str) -> dict[str, Any]:\n    with open(scriptfile, encoding=\"utf8\") as f:\n        script = f.read()\n\n    name = \"script\"\n    matches = list(\n        filter(lambda m: m.group(\"type\") == name, re.finditer(REGEX, script))\n    )\n\n    if len(matches) > 1:\n        raise PEP723Exception(f\"Multiple {name!r} blocks found in {scriptfile!r}\")\n    elif len(matches) == 1:\n        content = \"\".join(\n            line[2:] if line.startswith(\"# \") else line[1:]\n            for line in matches[0].group(\"content\").splitlines(keepends=True)\n        )\n        try:\n            metadata = tomllib.loads(content)\n        except Exception as exc:\n            raise PEP723Exception(f\"Failed to parse TOML in {scriptfile!r}\") from exc\n    else:\n        raise PEP723Exception(\n            f\"File does not contain {name!r} metadata: {scriptfile!r}\"\n        )\n\n    return metadata\n","sourceCodeStart":8,"sourceCodeEnd":42,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/req/pep723.py#L8-L42","documentation":"PEP 723 inline script metadata uses exactly one '# /// script' fenced block in a Python script. pip's pep723_metadata() function found more than one matching block and raised PEP723Exception. A script must have at most one inline metadata block.","triggerScenarios":"A Python script passed to pip's PEP 723 support (e.g. pip run script.py) contains two separate '# /// script' ... '# ///' sections. This can happen when merging scripts or when an editor/tool inserts a second metadata block.","commonSituations":"Concatenating two scripts that each had their own metadata block. An IDE plugin or tooling that auto-generates a metadata block without checking for an existing one. Copy-paste of a dependencies section.","solutions":["Search the script for all '# /// script' markers and keep only one","Merge the dependencies from duplicate blocks into a single '# /// script' block","Use a text editor or grep to locate the blocks: grep -n '# /// script' script.py"],"exampleFix":"# before — two blocks in script.py:\n# /// script\n# dependencies = [\"requests\"]\n# ///\n# ... later ...\n# /// script\n# dependencies = [\"rich\"]\n# ///\n\n# after — single merged block:\n# /// script\n# dependencies = [\"requests\", \"rich\"]\n# ///","handlingStrategy":"validation","validationCode":"import re\n\nREGEX = r\"(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\\s(?P<content>(^#(| .*)$\\s)+)^# ///$\"\n\ndef count_script_blocks(filepath: str) -> int:\n    with open(filepath) as f:\n        script = f.read()\n    return len([m for m in re.finditer(REGEX, script) if m.group(\"type\") == \"script\"])\n\nif count_script_blocks(\"script.py\") > 1:\n    print(\"Duplicate PEP 723 blocks detected — merge them\")","typeGuard":"def has_single_pep723_block(filepath: str) -> bool:\n    \"\"\"Type guard: True if the file has exactly one '# /// script' block.\"\"\"\n    import re\n    regex = r\"(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\\s(?P<content>(^#(| .*)$\\s)+)^# ///$\"\n    with open(filepath) as f:\n        matches = [m for m in re.finditer(regex, f.read()) if m.group(\"type\") == \"script\"]\n    return len(matches) == 1","tryCatchPattern":"from pip._internal.req.pep723 import pep723_metadata, PEP723Exception\n\ntry:\n    meta = pep723_metadata(\"script.py\")\nexcept PEP723Exception as e:\n    if \"Multiple\" in e.msg:\n        print(\"Fix: merge duplicate '# /// script' blocks into one\")\n    else:\n        raise","preventionTips":["When merging scripts, search for '# /// script' and keep only one block","Use a pre-commit hook that checks for duplicate PEP 723 blocks","After editing inline metadata, grep for '# /// script' to confirm exactly one block"],"tags":["pip","pep723","inline-script","metadata","parsing"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}