{"record":{"id":"e0617b368a3c6443","repo":"langchain-ai/deepagents","slug":"invalid-marketplace-url","errorCode":null,"errorMessage":"Invalid marketplace URL","messagePattern":"Invalid marketplace URL","errorType":"exception","errorClass":"MarketplaceError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/plugins/marketplace.py","lineNumber":174,"sourceCode":"        msg = \"Please enter a marketplace source\"\n        raise MarketplaceError(msg)\n\n    ssh_match = _SSH_GIT_RE.match(value)\n    if ssh_match:\n        return RepositoryMarketplaceSource(\n            source_type=\"git\", value=ssh_match.group(1), ref=ssh_match.group(2)\n        )\n\n    if value.startswith(\"http://\"):\n        msg = \"Remote marketplace sources must use https\"\n        raise MarketplaceError(msg)\n    if value.startswith(\"https://\"):\n        url, _, ref = value.partition(\"#\")\n        try:\n            parsed = urlparse(url)\n        except ValueError as exc:\n            msg = \"Invalid marketplace URL\"\n            raise MarketplaceError(msg) from exc\n        path = parsed.path\n        if path.endswith(\".git\") or \"/_git/\" in path:\n            return RepositoryMarketplaceSource(\n                source_type=\"git\", value=url, ref=ref or None\n            )\n        if parsed.hostname in {\"github.com\", \"www.github.com\"}:\n            parts = [part for part in path.split(\"/\") if part]\n            if len(parts) == _GITHUB_REPO_PART_COUNT:\n                repo_path = \"/\".join(parts)\n                git_url = urlunparse(parsed._replace(path=f\"/{repo_path}.git\"))\n                return RepositoryMarketplaceSource(\n                    source_type=\"git\", value=git_url, ref=ref or None\n                )\n            if len(parts) > _GITHUB_REPO_PART_COUNT:\n                msg = \"GitHub marketplace URLs must contain exactly owner/repo\"\n                raise MarketplaceError(msg)\n        return UrlMarketplaceSource(source_type=\"url\", value=url)\n","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/plugins/marketplace.py#L156-L192","documentation":"When a `https://` source is parsed, the URL is passed to `urlparse` (marketplace.py:168-174). If `urlparse` raises `ValueError` — typically because the URL contains characters it cannot handle, such as an invalid IPv6 literal in brackets or a port that is not numeric — the library wraps it in a `MarketplaceError` with this message. It is a defensive guard so malformed URLs fail with a domain-specific error instead of leaking `ValueError`.","triggerScenarios":"`parse_marketplace_source('https://[::1/marketplace.json')` (unterminated bracketed IPv6), `https://example.com:port/x` (non-numeric port), or URLs containing control characters, called directly or through `add_marketplace_source` / `_plugin_repository_source`.","commonSituations":"Hand-edited config files with typos in bracketed IPv6 hosts; template variables that expand to malformed URLs (e.g. `https://{{host}}:port/`); pasting URLs with stray whitespace-control characters from documents.","solutions":["Inspect the URL for invalid port numbers or malformed bracketed IPv6 hosts and fix them.","Validate the URL with `urllib.parse.urlparse` in a quick REPL check to see the underlying `ValueError`.","If the URL comes from an env var or template, print/expand it to confirm the interpolated value is a well-formed https URL."],"exampleFix":"// before\nsource = \"https://[::1/marketplace.json\"  # malformed IPv6\n// after\nsource = \"https://[::1]/marketplace.json\"","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\n\ndef validate_https_url(raw: str) -> str:\n    url = raw.partition(\"#\")[0]\n    if not url.startswith(\"https://\"):\n        raise ValueError(\"source must be an https URL\")\n    urlparse(url)  # raises ValueError on malformed URLs\n    return raw","typeGuard":"from urllib.parse import urlparse\n\ndef is_parseable_https_url(value: str) -> bool:\n    try:\n        parsed = urlparse(value.partition(\"#\")[0])\n    except ValueError:\n        return False\n    return parsed.scheme == \"https\" and bool(parsed.hostname)","tryCatchPattern":"try:\n    source = parse_marketplace_source(raw)\nexcept MarketplaceError as exc:\n    if \"Invalid marketplace URL\" in str(exc):\n        log.warning(\"Malformed https URL: %r\", raw)\n        raise ValueError(f\"Fix the URL (check ports/IPv6 brackets): {raw}\") from exc\n    raise","preventionTips":["Never build URLs by raw string concatenation of host/port templates; use urllib.parse.","Test bracketed IPv6 hosts and custom ports before shipping config.","Escape or strip control characters from URLs sourced from env vars or templates."],"tags":["validation","url","urlparse"],"backgroundTag":"malformed-url","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}