{"record":{"id":"f3c53761eb344245","repo":"usestrix/strix","slug":"invalid-request-line-format","errorCode":null,"errorMessage":"Invalid request line format","messagePattern":"Invalid request line format","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strix/tools/proxy/caido_api.py","lineNumber":262,"sourceCode":"        body_truncated = len(body_text) > _RESPONSE_BODY_MAX_CHARS\n        if body_truncated:\n            body_text = body_text[:_RESPONSE_BODY_MAX_CHARS]\n        return {\n            \"status_code\": status_code,\n            \"length\": len(body_bytes),\n            \"headers\": headers,\n            \"body\": body_text,\n            \"body_truncated\": body_truncated,\n        }\n    except Exception:  # noqa: BLE001 - tolerate any malformed raw bytes; None signals \"unparseable\" to the caller.\n        return None\n\n\ndef parse_raw_request(raw_content: str) -> dict[str, Any]:\n    lines = raw_content.split(\"\\n\")\n    request_line = lines[0].strip().split(\" \")\n    if len(request_line) < 2:\n        raise ValueError(\"Invalid request line format\")\n    method, url_path = request_line[0], request_line[1]\n\n    parsed_headers: dict[str, str] = {}\n    body_start = 0\n    for i, line in enumerate(lines[1:], 1):\n        if line.strip() == \"\":\n            body_start = i + 1\n            break\n        if \":\" in line:\n            key, value = line.split(\":\", 1)\n            parsed_headers[key.strip()] = value.strip()\n\n    body = \"\\n\".join(lines[body_start:]).strip() if body_start < len(lines) else \"\"\n    return {\"method\": method, \"url_path\": url_path, \"headers\": parsed_headers, \"body\": body}\n\n\ndef full_url_from_components(\n    original: Any,","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/tools/proxy/caido_api.py#L244-L280","documentation":"parse_raw_request() splits the raw HTTP request text and requires the first line to contain at least two whitespace-separated tokens (method and URL path). Fewer tokens raises ValueError('Invalid request line format'). It is the strict parser used when replaying/modifying captured Caido requests.","triggerScenarios":"repeat_request() fetches the stored request's raw bytes and hands them to parse_raw_request; if the first line is empty, a single token, or whitespace-only (mangled capture, empty raw, binary garbage decoded via errors='replace'), the parse fails.","commonSituations":"Captured request bodies stored without a proper request line; Caido entry containing only a body or response bytes; upstream tool wrote malformed raw content into the proxy history.","solutions":["Inspect the stored raw request in Caido (the request_id from the error context) and confirm line 1 looks like 'GET /path HTTP/1.1'.","Skip/ignore the malformed entry and replay from a correctly captured request.","Re-capture the traffic so the proxy history contains a well-formed request line.","If automating, pre-check `len(raw.splitlines()[0].split()) >= 2` before calling parse functions."],"exampleFix":"# before: raw content starts with an empty/blank line or body only\n\"\\n\\n{\"a\":1}\"\n\n# after: raw content starts with a valid request line\n\"POST /api HTTP/1.1\\nHost: t.example\\n\\n{\\\"a\\\":1}\"","handlingStrategy":"validation","validationCode":"def has_request_line(raw: str) -> bool:\n    first = raw.split(\"\\n\", 1)[0].strip()\n    return len(first.split()) >= 2\n\nraw = result.request.raw.decode(\"utf-8\", errors=\"replace\")\nif not has_request_line(raw):\n    skip(request_id)  # don't hand it to parse_raw_request","typeGuard":"def is_parseable_raw_request(raw: object) -> bool:\n    if not isinstance(raw, (str, bytes)):\n        return False\n    text = raw.decode(\"utf-8\", errors=\"replace\") if isinstance(raw, bytes) else raw\n    return len(text.split(\"\\n\")[0].strip().split(\" \")) >= 2","tryCatchPattern":"try:\n    components = parse_raw_request(raw_str)\nexcept ValueError as exc:\n    if \"request line\" in str(exc):\n        log.warning(\"skipping malformed capture %s\", request_id)\n        continue\n    raise","preventionTips":["Filter proxy history entries with a request-line pre-check before batch replay.","Re-capture traffic cleanly instead of hand-crafting raw request files.","Treat 'unparseable raw' from Caido (parse returns None) and this ValueError as the same skip class."],"tags":["proxy","caido","http-parsing","replay"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}