{"record":{"id":"429ee38c2e19de19","repo":"langchain-ai/deepagents","slug":"remote-source-must-be-a-validated-absolute-https-u","errorCode":null,"errorMessage":"remote_source must be a validated absolute HTTPS URL","messagePattern":"remote_source must be a validated absolute HTTPS URL","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/configuration/types.py","lineNumber":137,"sourceCode":"        text, so \"only a validated URL reaches here\" is a security invariant.\n        It held by convention -- one construction site in each of two modules\n        -- and `ProviderStatus` is public, so a third site is a rejected\n        source, credentials and all, in a `doctor` row. This restates the\n        canonical remote-source validator and also requires its normalized\n        output: the point is that an unvalidated string cannot get in.\n\n        Raises:\n            ValueError: If `remote_source` is not the normalized output of the\n                remote-source validator.\n        \"\"\"\n        source = self.remote_source\n        if source is None:\n            return\n        msg = \"remote_source must be a validated absolute HTTPS URL\"\n        try:\n            normalized = _validate_remote_source_url(source)\n        except ValueError as exc:\n            raise ValueError(msg) from exc\n        if normalized != source:\n            raise ValueError(msg)\n\n    @property\n    def usable(self) -> bool:\n        \"\"\"Whether the provider can safely participate in resolution.\n\n        `MISSING` is usable because no file at an authoritative path means the\n        administrator deployed no policy. `INDETERMINATE` is not: the path\n        itself is a guess, so an empty read proves nothing about what policy\n        the administrator deployed.\n        \"\"\"\n        return self.health in {ProviderHealth.OK, ProviderHealth.MISSING}\n\n\n@dataclass(frozen=True, slots=True)\nclass TomlSnapshot:\n    \"\"\"One parsed TOML source and its health.","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/configuration/types.py#L119-L155","documentation":"Raised in `__post_init__` (types.py:137) when the URL fails validation entirely: `_validate_remote_source_url` raised a ValueError (non-HTTPS, credentials, query/fragment, bad port, or non-ASCII/unparseable), and it is re-raised with the generic message that remote_source must be a validated absolute HTTPS URL. The original specific reason is chained via `from exc`.","triggerScenarios":"Constructing the descriptor dataclass with a remote_source that fails any rule in _validate_remote_source_url — e.g. a non-string/unparseable value, non-ASCII characters ('https://exämple.com/x.toml'), scheme missing, credentials, query, fragment, or bad port.","commonSituations":"Loading config from a TOML/env value that was never normalized; internationalized domain names pasted in Unicode form; empty or malformed strings produced by string interpolation; passing a local file path ('file:///...' or '/home/me/config.toml') where an HTTPS URL is required.","solutions":["Pre-normalize the URL through the library's own validation/normalization helper before constructing the object, then assign the normalized string","Fix the underlying defect indicated by the chained __cause__ (scheme, credentials, query/fragment, port, or ASCII)","Convert local paths to hosted HTTPS URLs — file paths are not valid remote sources","For IDNs, use the punycode (ASCII) form of the hostname"],"exampleFix":"// before\nRemoteProviderDescriptor(remote_source=\"/home/me/config.toml\")  # not a URL\n// after\nRemoteProviderDescriptor(remote_source=\"https://config.example.com/me/config.toml\")","handlingStrategy":"validation","validationCode":"def check_remote_source(source: str) -> str:\n    from deepagents_code.configuration.types import _validate_remote_source_url\n    return _validate_remote_source_url(source)  # raises with specific reason\n\nnormalized = check_remote_source(candidate)  # call before constructing","typeGuard":"def looks_like_https_url(value: object) -> bool:\n    from urllib.parse import urlparse\n    return (\n        isinstance(value, str)\n        and value.isascii()\n        and urlparse(value).scheme.lower() == \"https\"\n        and bool(urlparse(value).hostname)\n    )","tryCatchPattern":"try:\n    descriptor = RemoteProviderDescriptor(remote_source=src)\nexcept ValueError as exc:\n    logger.debug(\"underlying reason: %s\", exc.__cause__)\n    raise ConfigError(f\"remote_source {src!r} is not a validated HTTPS URL: {exc.__cause__}\") from exc","preventionTips":["Validate and normalize at config-load time, before constructing descriptors","Reject file:// or local paths early — remote sources must be HTTPS","Use the punycode form for internationalized hostnames","Inspect the chained __cause__ to learn the exact rule violated"],"tags":["validation","configuration","url","https"],"backgroundTag":"invalid-remote-source-url","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}