langchain-ai/deepagents · error · ValueError

remote source must not contain credentials

Error message

remote source must not contain credentials

What it means

Raised by `_validate_remote_source_url` when the parsed HTTPS URL embeds userinfo credentials (a username or password, e.g. 'https://user:pass@example.com/...'). The library forbids credentials in remote source URLs so secrets do not leak into logs, caches, or serialized configuration; authentication must happen out of band.

Source

Thrown at libs/code/deepagents_code/configuration/types.py:80

        msg = "remote source is too long"
        raise ValueError(msg)
    if any(char.isspace() or not char.isprintable() for char in source):
        msg = "remote source must not contain whitespace or control characters"
        raise ValueError(msg)
    try:
        parsed = urlsplit(source)
    except ValueError as exc:
        msg = "remote source is not a valid URL"
        raise ValueError(msg) from exc
    if not source.isascii():
        msg = "remote source must contain only ASCII URI characters"
        raise ValueError(msg)
    if parsed.scheme.lower() != "https" or not parsed.hostname:
        msg = "remote source must be an absolute HTTPS URL"
        raise ValueError(msg)
    if parsed.username is not None or parsed.password is not None:
        msg = "remote source must not contain credentials"
        raise ValueError(msg)
    if parsed.query or parsed.fragment:
        msg = "remote source must not contain a query string or fragment"
        raise ValueError(msg)
    try:
        port = parsed.port
    except ValueError as exc:
        msg = "remote source has an invalid port"
        raise ValueError(msg) from exc
    host = parsed.hostname.rstrip(".")
    netloc = f"[{host}]" if ":" in host else host
    if port is not None:
        netloc = f"{netloc}:{port}"
    return parsed._replace(scheme="https", netloc=netloc).geturl()


@dataclass(frozen=True, slots=True)
class ProviderStatus:
    """Health and safe diagnostic detail for one provider."""

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Remove the username/password from the URL (strip everything up to and including '@' before the host)
  2. Move the credential to an environment variable or credential helper consumed by the fetcher, not the URL
  3. If using a git host, use a public raw HTTPS URL for the config file instead of a clone URL
  4. Rotate the credential if it was already committed to a config file — it may have been captured in logs

Example fix

// before
RemoteSource(source="https://ghp_abc123@raw.githubusercontent.com/org/repo/main/config.toml")
// after
RemoteSource(source="https://raw.githubusercontent.com/org/repo/main/config.toml")
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse

def has_url_credentials(source: str) -> bool:
    parsed = urlparse(source)
    return parsed.username is not None or parsed.password is not None

assert not has_url_credentials(src), "strip credentials from remote_source"

Type guard

def is_credential_free_url(value: str) -> bool:
    parsed = urlparse(value)
    return parsed.username is None and parsed.password is None

Try / catch

try:
    RemoteSource(source=src)
except ValueError as exc:
    if "credentials" in str(exc):
        src = re.sub(r"^[a-z][a-z0-9+.-]*://[^/@]*@", lambda m: m.group(0).split('://')[0] + '://', src)
    raise ConfigError("remove credentials from remote_source; use env vars") from exc

Prevention

When it happens

Trigger: Constructing the remote-source dataclass with a URL containing '@' userinfo such as 'https://token@github.com/org/repo/config.toml' or 'https://user:pass@example.com/x.toml' — parsed.username or parsed.password is not None.

Common situations: Copying an authenticated git/clone URL (personal access token in the URL) into a remote_source field; sharing a colleague's bookmarked URL that embeds an API token; older tooling that recommended token-in-URL auth.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/25a836d0e19df205. Report an issue: GitHub.