{"record":{"id":"34b81b5f89c9008f","repo":"github/spec-kit","slug":"catalog-source-id-url-is-malformed-url","errorCode":null,"errorMessage":"Catalog '{source_id}' URL is malformed: {url}","messagePattern":"Catalog '(.+?)' URL is malformed: (.+?)","errorType":"exception","errorClass":"BundlerError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/bundler/services/adapters.py","lineNumber":83,"sourceCode":"\n\ndef _validate_remote_url(source_id: str, url: str) -> None:\n    \"\"\"Restrict remote catalogs to HTTPS (HTTP only for localhost) with a host.\n\n    Mirrors ``specify_cli.catalogs`` URL validation to avoid MITM/downgrade\n    issues before any network call.\n    \"\"\"\n    # A malformed authority (e.g. an unclosed IPv6 bracket ``https://[::1``)\n    # makes urlparse / hostname access raise ValueError. This function's\n    # contract is to raise BundlerError for a bad URL, so surface that as a\n    # clean error rather than leaking a raw ValueError to the caller.\n    try:\n        parsed = urlparse(url)\n        hostname = parsed.hostname\n        # Accessing ``port`` performs urllib's syntax/range validation.\n        _ = parsed.port\n    except ValueError:\n        raise BundlerError(\n            f\"Catalog '{source_id}' URL is malformed: {url}\"\n        ) from None\n    is_localhost = hostname in (\"localhost\", \"127.0.0.1\", \"::1\")\n    if parsed.scheme != \"https\" and not (parsed.scheme == \"http\" and is_localhost):\n        raise BundlerError(\n            f\"Catalog '{source_id}' URL must use HTTPS (got {parsed.scheme}://). \"\n            \"HTTP is only allowed for localhost.\"\n        )\n    # Check hostname, not netloc: netloc is truthy for host-less URLs like\n    # \"https://:8080\" or \"https://user@...\", so requiring netloc would let\n    # those through even though they carry no host. hostname is None in those\n    # cases. Mirrors the fix in ``specify_cli.catalogs`` (#3210).\n    if not hostname:\n        raise BundlerError(\n            f\"Catalog '{source_id}' URL must be a valid URL with a host: {url}\"\n        )\n\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/bundler/services/adapters.py#L65-L101","documentation":"Error \"Catalog '{source_id}' URL is malformed: {url}\" thrown in github/spec-kit.","triggerScenarios":"Thrown at src/specify_cli/bundler/services/adapters.py:83 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Correct the catalog source URL in the catalog config so it is a well-formed URL (scheme://host/path)."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}