affaan-m/ECC · error · ValueError

remote import URL is missing a hostname

Error message

remote import URL is missing a hostname

What it means

Raised by _validate_import_url when urlparse produces an empty/absent hostname for the import source. Without a hostname the CLI cannot resolve or reach any server, so the URL is rejected before network access. Typically indicates a malformed or scheme-relative URL.

Solutions

  1. Supply a complete URL including the host: https://example.com/path.
  2. Validate before calling: bool(urllib.parse.urlparse(source).hostname).
  3. Fix template/config values that left the host empty.
  4. If importing local content, use the local import path/flag instead of the remote URL flag.

Example fix

# before
source = base_url + "/instincts.yaml"  # base_url was ""
# after
base_url = base_url or "https://instincts.example.com"
source = f"{base_url}/instincts.yaml"
assert urllib.parse.urlparse(source).hostname
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse
if not urlparse(source).hostname:
    raise ValueError(f"URL missing hostname: {source}")

Try / catch

try:
    cli_import(url=source)
except ValueError as e:
    if "missing a hostname" in str(e):
        print(f"malformed URL: {source}")

Prevention

When it happens

Trigger: Passing sources like 'https://' (no host), '//example.com/file', 'file:///etc/passwd', or plain paths/strings that urlparse cannot interpret as host-bearing URLs.

Common situations: String concatenation bugs that drop the host portion; config templates with unfilled placeholders (https://{{HOST}}/x); users passing a local file path to a command that expects a URL.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/7f70edc8bfdcb663. Report an issue: GitHub.

Appendix: source

Thrown at skills/continuous-learning-v2/scripts/instinct-cli.py:195

    """Validate instinct IDs before using them in filenames."""
    if not instinct_id or len(instinct_id) > 128:
        return False
    if "/" in instinct_id or "\\" in instinct_id:
        return False
    if ".." in instinct_id:
        return False
    if instinct_id.startswith("."):
        return False
    return bool(re.match(r"^[A-Za-z0-9][A-Za-z0-9._-]*$", instinct_id))


def _validate_import_url(source: str) -> str:
    """Validate remote instinct imports before opening a network connection."""
    parsed = urllib.parse.urlparse(source)
    if parsed.scheme != "https":
        raise ValueError("remote instinct imports require https URLs")
    if not parsed.hostname:
        raise ValueError("remote import URL is missing a hostname")

    try:
        addr_infos = socket.getaddrinfo(parsed.hostname, parsed.port or 443, type=socket.SOCK_STREAM)
    except socket.gaierror as exc:
        raise ValueError(f"remote import host could not be resolved: {parsed.hostname}") from exc

    for family, _, _, _, sockaddr in addr_infos:
        host = sockaddr[0]
        try:
            ip = ipaddress.ip_address(host)
        except ValueError:
            continue
        if (
            ip.is_private
            or ip.is_loopback
            or ip.is_link_local
            or ip.is_multicast
            or ip.is_reserved

View on GitHub (pinned to 8321021c54)