{"id":"21bf6f737f102a10","repo":"pypa/pip","slug":"unexpected-type-type-value-name-expected","errorCode":null,"errorMessage":"Unexpected type {type(value).__name__} (expected {expected_type.__name__})","messagePattern":"Unexpected type (.+?) \\(expected (.+?)\\)","errorType":"validation","errorClass":"DirectUrlValidationError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/direct_url.py","lineNumber":51,"sourceCode":"\nclass _FromMappingProtocol(Protocol):  # pragma: no cover\n    @classmethod\n    def _from_dict(cls, d: Mapping[str, Any]) -> Self: ...\n\n\n_FromMappingProtocolT = TypeVar(\"_FromMappingProtocolT\", bound=_FromMappingProtocol)\n\n\ndef _json_dict_factory(data: list[tuple[str, Any]]) -> dict[str, Any]:\n    return {key: value for key, value in data if value is not None}\n\n\ndef _get(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T | None:\n    \"\"\"Get a value from the dictionary and verify it's the expected type.\"\"\"\n    if (value := d.get(key)) is None:\n        return None\n    if not isinstance(value, expected_type):\n        raise DirectUrlValidationError(\n            f\"Unexpected type {type(value).__name__} \"\n            f\"(expected {expected_type.__name__})\",\n            context=key,\n        )\n    return value\n\n\ndef _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T:\n    \"\"\"Get a required value from the dictionary and verify it's the expected type.\"\"\"\n    if (value := _get(d, expected_type, key)) is None:\n        raise _DirectUrlRequiredKeyError(key)\n    return value\n\n\ndef _get_object(\n    d: Mapping[str, Any], target_type: type[_FromMappingProtocolT], key: str\n) -> _FromMappingProtocolT | None:\n    \"\"\"Get a dictionary value from the dictionary and convert it to a dataclass.\"\"\"","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/packaging/direct_url.py#L33-L69","documentation":"Raised by `packaging.direct_url._get` when a key is present in the JSON dict but its value is not of the expected type (e.g. `url` is a list instead of str, `editable` is a string instead of bool). This is the schema-validation guard for PEP 610 direct URL JSON, normally wrapped into a `DirectUrlValidationError` with the offending key as `context`.","triggerScenarios":"Calling `DirectUrl.from_dict(d)` (or pip loading a `direct_url.json` from an installed dist) where `d['url']` is not a str, `d['subdirectory']` is not a str, `d['vcs_info']['commit_id']` is not a str, or `d['dir_info']['editable']` is not a bool.","commonSituations":"Hand-edited `direct_url.json` in site-packages; a tool that emits JSON with coerced types (e.g. quoting booleans); a corrupted install record after an interrupted pip install; a custom installer that writes non-spec records.","solutions":["Reinstall the package so pip regenerates a spec-compliant `direct_url.json`","Inspect `<env>/site-packages/<dist>-*.dist-info/direct_url.json` and fix the offending key's type","Validate the dict against PEP 610 schema before calling `from_dict`"],"exampleFix":"// before\nDirectUrl.from_dict({'url': 123, 'archive_info': {}})\n// after\nDirectUrl.from_dict({'url': 'https://example.com/pkg.tar.gz', 'archive_info': {}})","handlingStrategy":"validation","validationCode":"def validate_direct_url_dict(d: dict) -> None:\n    if 'url' in d and not isinstance(d['url'], str):\n        raise ValueError('url must be str')\n    if 'subdirectory' in d and not isinstance(d['subdirectory'], str):\n        raise ValueError('subdirectory must be str')","typeGuard":"def is_direct_url_compatible(d: object) -> bool:\n    return isinstance(d, dict) and all(\n        (k not in d) or isinstance(d[k], t)\n        for k, t in (('url', str), ('subdirectory', str))\n    )","tryCatchPattern":"from packaging.direct_url import DirectUrl, DirectUrlValidationError\ntry:\n    du = DirectUrl.from_dict(d)\nexcept DirectUrlValidationError as e:\n    raise ValueError(f'bad direct_url.json: {e}') from e","preventionTips":["Never hand-edit direct_url.json; let pip regenerate it","Validate JSON types against PEP 610 schema before calling from_dict","Reinstall packages whose install metadata errors out"],"tags":["packaging","direct-url","pep610","input-validation"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}