{"record":{"id":"120a5c4a137df065","repo":"usestrix/strix","slug":"invalid-caido-url-base-url","errorCode":null,"errorMessage":"Invalid Caido URL: {base_url}","messagePattern":"Invalid Caido URL: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strix/tools/proxy/caido_api.py","lineNumber":68,"sourceCode":"    \"host\": (\"req\", \"host\"),\n    \"method\": (\"req\", \"method\"),\n    \"path\": (\"req\", \"path\"),\n    \"source\": (\"req\", \"source\"),\n    \"status_code\": (\"resp\", \"code\"),\n    \"response_time\": (\"resp\", \"roundtrip\"),\n    \"response_size\": (\"resp\", \"length\"),\n}\n\n\ndef caido_url() -> str:\n    return os.environ.get(\"STRIX_CAIDO_URL\", _DEFAULT_CAIDO_URL).rstrip(\"/\")\n\n\ndef _graphql_url() -> str:\n    base_url = caido_url()\n    parsed = urlparse(base_url)\n    if parsed.scheme not in {\"http\", \"https\"} or not parsed.netloc:\n        raise ValueError(f\"Invalid Caido URL: {base_url}\")\n    return f\"{base_url}/graphql\"\n\n\ndef _login_as_guest() -> str:\n    body = json.dumps({\"query\": \"mutation { loginAsGuest { token { accessToken } } }\"}).encode(\n        \"utf-8\"\n    )\n    req = urllib.request.Request(  # noqa: S310\n        _graphql_url(),\n        data=body,\n        headers={\"Content-Type\": \"application/json\"},\n        method=\"POST\",\n    )\n    with urllib.request.urlopen(req, timeout=10) as resp:  # noqa: S310  # nosec B310\n        payload = json.loads(resp.read())\n    return str(payload[\"data\"][\"loginAsGuest\"][\"token\"][\"accessToken\"])\n\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/tools/proxy/caido_api.py#L50-L86","documentation":"Caido proxy integration derives its GraphQL endpoint from STRIX_CAIDO_URL (default applied when unset). _graphql_url() parses the base URL and requires an http/https scheme and a non-empty network location; otherwise it raises ValueError. Every GraphQL call (login, search, repeat) funnels through this, so it fails on first client use.","triggerScenarios":"Setting STRIX_CAIDO_URL to a value without a scheme ('localhost:8080') or without a host ('http://'), or to a non-HTTP scheme ('ftp://caido'). Any Caido tool call then raises before any network traffic is attempted.","commonSituations":"Users omit the http:// prefix because browsers add it implicitly; trailing config drift after Caido moves ports; copying a ws:// or grpc:// URL by mistake; empty string after .rstrip('/') in caido_url().","solutions":["Set a fully qualified URL including scheme and host: export STRIX_CAIDO_URL=http://127.0.0.1:8080.","Confirm the port matches Caido's listening port in its settings.","Ensure the variable is not set to an empty string; unset it to use the default.","Check for scheme typos like 'http//' or 'http:/localhost'."],"exampleFix":"# before\nexport STRIX_CAIDO_URL=localhost:8080\n\n# after\nexport STRIX_CAIDO_URL=http://localhost:8080","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\nimport os\n\ndef caido_url_valid(url: str) -> bool:\n    p = urlparse(url)\n    return p.scheme in {\"http\", \"https\"} and bool(p.netloc)\n\nurl = os.environ.get(\"STRIX_CAIDO_URL\", \"\")\nassert not url or caido_url_valid(url.rstrip(\"/\")), \"STRIX_CAIDO_URL must be http(s)://host[:port]\"","typeGuard":null,"tryCatchPattern":"try:\n    await caido_call(...)\nexcept ValueError as exc:\n    if \"Invalid Caido URL\" in str(exc):\n        raise SystemExit(\"fix STRIX_CAIDO_URL to http://host:port\") from exc\n    raise","preventionTips":["Always include the scheme when configuring STRIX_CAIDO_URL.","Never set it to an empty string — unset it to fall back to the default.","Add a startup smoke check that pings the Caido GraphQL endpoint before a long scan."],"tags":["config","environment","proxy","caido","url"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}