Panniantong/Agent-Reach · error · ValueError

only public HTTP(S) URLs are allowed

Error message

only public HTTP(S) URLs are allowed

What it means

First rejection branch of normalize_public_http_url: the raw input is not acceptable ASCII-ish text — it is empty, contains a backslash, any whitespace/control character (<0x20 or 0x7F). This is input sanitization before any URL parsing; the strict character whitelist blocks header-injection and parser-confusion tricks.

Source

Thrown at agent_reach/utils/url.py:58

    try:
        packed = socket.inet_aton(host)
    except OSError:
        return None
    return ipaddress.IPv4Address(packed)


def normalize_public_http_url(url: str) -> str:
    """Normalize a URL or reject targets that are not clearly public HTTP(S)."""
    candidate = str(url or "").strip()
    if (
        not candidate
        or "\\" in candidate
        or any(
            character.isspace() or ord(character) < 0x20 or ord(character) == 0x7F
            for character in candidate
        )
    ):
        raise ValueError("only public HTTP(S) URLs are allowed")
    if "://" not in candidate:
        candidate = f"https://{candidate}"

    try:
        parsed = urlsplit(candidate)
        host = (parsed.hostname or "").lower().rstrip(".")
        # Accessing the port rejects malformed or out-of-range authorities.
        _ = parsed.port
    except (TypeError, ValueError):
        raise ValueError("only public HTTP(S) URLs are allowed") from None

    literal_address = _literal_ip_address(host)
    if (
        parsed.scheme.lower() not in {"http", "https"}
        or not host
        or parsed.username is not None
        or parsed.password is not None
        or "%" in host

View on GitHub (pinned to 93ae1d18c3)

Solutions

  1. Strip the input before calling: str(url).strip() and remove surrounding quotes/newlines
  2. Reject or escape backslashes — if the value is a Windows path it is not a URL at all
  3. Sanitize upstream: when URLs come from files/LLMs, filter lines with control characters before passing them in

Example fix

# before
url = open('urls.txt').readline()  # 'https://x.com/a\n'
normalize_public_http_url(url)  # ValueError

# after
url = open('urls.txt').readline().strip()
normalize_public_http_url(url)
Defensive patterns

Strategy: validation

Validate before calling

def is_clean_url_input(candidate: str) -> bool:
    if not candidate:
        return False
    if "\\" in candidate:
        return False
    return not any(ord(c) < 0x20 or ord(c) == 0x7F or c.isspace() for c in candidate)

Try / catch

from agent_reach.utils.url import normalize_public_http_url
try:
    url = normalize_public_http_url(raw)
except ValueError:
    cleaned = "".join(raw.split())  # last-resort whitespace strip
    url = normalize_public_http_url(cleaned) if cleaned and "\\" not in cleaned else None

Prevention

When it happens

Trigger: Passing an empty/None-ish string, a URL with a trailing newline or space ('https://x.com/a\n'), a URL containing a literal backslash, or embedded tab/CR — common when reading URLs from files, CSVs, clipboard, or LLM output without stripping.

Common situations: URLs scraped or generated with surrounding whitespace; copy-paste introducing zero-width or control chars; template strings with accidental newlines; Windows-style backslash paths passed instead of URLs.

Related errors


AI-assisted analysis of Panniantong/Agent-Reach@93ae1d18c3 (2026-08-14). Data as JSON: /api/errors/9c25ad0ae4cf38c2. Report an issue: GitHub.