{"record":{"id":"c09d1847cb436890","repo":"pypa/pip","slug":"path-or-url-must-be-provided","errorCode":null,"errorMessage":"path or url must be provided","messagePattern":"path or url must be provided","errorType":"validation","errorClass":"PylockValidationError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/pylock.py","lineNumber":247,"sourceCode":"    d: Mapping[str, Any], target_item_type: type[_FromMappingProtocolT], key: str\n) -> Sequence[_FromMappingProtocolT]:\n    \"\"\"Get a required list value from the dictionary and convert its items to a\n    dataclass.\"\"\"\n    if (result := _get_sequence_of_objects(d, target_item_type, key)) is None:\n        raise _PylockRequiredKeyError(key)\n    return result\n\n\ndef _validate_normalized_name(name: str) -> NormalizedName:\n    \"\"\"Validate that a string is a NormalizedName.\"\"\"\n    if not is_normalized_name(name):\n        raise PylockValidationError(f\"Name {name!r} is not normalized\")\n    return NormalizedName(name)\n\n\ndef _validate_path_url(path: str | None, url: str | None) -> None:\n    if not path and not url:\n        raise PylockValidationError(\"path or url must be provided\")\n\n\ndef _path_name(path: str | None) -> str | None:\n    if not path:\n        return None\n    # If the path is relative it MAY use POSIX-style path separators explicitly\n    # for portability\n    if \"/\" in path:\n        return path.rsplit(\"/\", 1)[-1]\n    elif \"\\\\\" in path:\n        return path.rsplit(\"\\\\\", 1)[-1]\n    else:\n        return path\n\n\ndef _url_name(url: str | None) -> str | None:\n    if not url:\n        return None","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/pylock.py#L229-L265","documentation":"Raised by _validate_path_url in pylock.py:245-247, called from the _from_dict of PackageVcs, PackageArchive, PackageSdist and PackageWheel. At least one of 'path' or 'url' must be a non-empty string; if both are missing/empty, PylockValidationError is raised (note: a vcs/archive/sdist/wheel still needs a fetchable location even when 'name' is set).","triggerScenarios":"A [[packages.vcs]] table with only type/commit-id but no path and no url; a sdist/archive/wheel entry with hashes and name but neither path nor url.","commonSituations":"Forgetting the source location; assuming 'name' implies a download URL.","solutions":["Add path = \"...\" or url = \"...\" to the vcs/archive/sdist/wheel entry.","For VCS entries ensure 'url' (remote) or 'path' (local checkout) is present."],"exampleFix":"# before\n[[packages]]\nname = \"x\"\n  [packages.vcs]\n  type = \"git\"\n  commit-id = \"abc\"\n# after\n[[packages]]\nname = \"x\"\n  [packages.vcs]\n  type = \"git\"\n  url = \"https://example.com/x.git\"\n  commit-id = \"abc\"","handlingStrategy":"validation","validationCode":"def has_path_or_url(path, url) -> bool:\n    return bool(path) or bool(url)\n","typeGuard":null,"tryCatchPattern":"from packaging.pylock import Pylock, PylockValidationError\n\ntry:\n    Pylock.from_dict(d)\nexcept PylockValidationError as e:\n    ...\n","preventionTips":["Always set path or url for every vcs/archive/sdist/wheel entry.","Do not assume 'name' supplies a fetchable location."],"tags":["pylock","validation","source-location"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}