usestrix/strix · error · ValueError
Invalid URL: {url}
Error message
Invalid URL: {url} What it means
build_raw_request() converts a logical request (method/url/headers/body) into a Caido ConnectionInfoInput plus raw bytes. It urlparse()s the URL and requires both a scheme and a netloc; otherwise ValueError. This catches malformed replay targets before any socket is opened.
Source
Thrown at strix/tools/proxy/caido_api.py:182
# "Field required" on the missing raw field. Always request both —
# the caller picks which one to surface via ``part``.
opts = RequestGetOptions(request_raw=True, response_raw=True)
return await client.request.get(request_id, opts)
_FRAMING_HEADERS = frozenset({"content-length", "transfer-encoding"})
def build_raw_request(
*,
method: str,
url: str,
headers: dict[str, str],
body: str,
) -> tuple[ConnectionInfoInput, bytes]:
parsed = urlparse(url)
if not parsed.scheme or not parsed.netloc:
raise ValueError(f"Invalid URL: {url}")
is_tls = parsed.scheme.lower() == "https"
host = parsed.hostname or ""
port = parsed.port or (443 if is_tls else 80)
path = parsed.path or "/"
if parsed.query:
path = f"{path}?{parsed.query}"
final_headers = {**headers}
final_headers.setdefault("Host", parsed.netloc)
final_headers.setdefault(
"User-Agent",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
)
# Framing headers inherited from the captured request describe the ORIGINAL
# body; once the body is modified for replay they are stale. We always send a
# plain (non-chunked) body with an explicit Content-Length, so drop any
# inherited Content-Length AND Transfer-Encoding (case-insensitively) andView on GitHub (pinned to 8551339130)
Solutions
- Pass modifications with an explicit absolute URL including scheme and host when replaying origin-form requests.
- Ensure the captured request retains a Host header so full_url_from_components can reconstruct the absolute URL.
- Validate the URL with urlparse before calling repeat_request and fix or skip malformed ones.
- If targeting a different host, set both the url and the Host header consistently in modifications.
Example fix
# before
await repeat_request(req_id, modifications={"url": "/api/login", ...})
# after
await repeat_request(req_id, modifications={"url": "https://target.example/api/login", ...}) Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def is_absolute_http_url(url: str) -> bool:
p = urlparse(url)
return p.scheme in {"http", "https"} and bool(p.netloc)
if not is_absolute_http_url(mods.get("url", "")):
mods["url"] = f"https://{host_from_host_header}{path}" # absolutize before replay Type guard
def is_replayable_url(url: object) -> bool:
if not isinstance(url, str):
return False
p = urlparse(url)
return p.scheme in {"http", "https"} and bool(p.netloc) Try / catch
try:
await repeat_request(request_id, modifications=mods)
except ValueError as exc:
if "Invalid URL" in str(exc):
continue # skip malformed replay target, log the id
raise Prevention
- Always pass an absolute URL (scheme + host) in replay modifications.
- Preserve Host headers when capturing so absolute URLs can be reconstructed.
- Validate modification payloads from LLM agents before replaying them.
When it happens
Trigger: Calling repeat_request (or build_raw_request directly) with a URL like '/api/foo' (no scheme/host), 'example.com/x' (no scheme), or 'http://' (no host). Usually the URL comes from full_url_from_components() reconstructing it from a captured raw request whose Host header or absolute-URI request line is missing.
Common situations: Replaying a captured request whose original form was origin-form (path-only) and no Host header survived; LLM-generated modification sets url to a relative path; proxy captures with mangled request lines.
Related errors
- Invalid Caido URL: {base_url}
- Invalid request line format
- Request {request_id} not found
- scope_id required for get
- scope_name required for create
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/5818b3bf82ef59f3.
Report an issue: GitHub.