{"record":{"id":"4192c7a30376235a","repo":"usestrix/strix","slug":"target-list-file-path-str-is-empty","errorCode":null,"errorMessage":"Target list file '{path_str}' is empty.","messagePattern":"Target list file '(.+?)' is empty\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strix/interface/utils.py","lineNumber":1231,"sourceCode":"\n    path = Path(path_str).expanduser()\n    if not path.is_file():\n        raise ValueError(f\"Target list file '{path_str}' is not an existing file.\")\n\n    try:\n        targets = [\n            target\n            for line in path.read_text(encoding=\"utf-8\").splitlines()\n            if (target := line.strip()) and not target.startswith(\"#\")\n        ]\n    except UnicodeDecodeError as e:\n        raise ValueError(f\"Target list file '{path_str}' must be valid UTF-8 text: {e!s}\") from e\n    except OSError as e:\n        raise ValueError(f\"Failed to read target list file '{path_str}': {e!s}\") from e\n\n    targets = [target for target in targets if target]\n    if not targets:\n        raise ValueError(f\"Target list file '{path_str}' is empty.\")\n    return targets\n\n\ndef sanitize_name(name: str) -> str:\n    sanitized = re.sub(r\"[^A-Za-z0-9._-]\", \"-\", name.strip())\n    return sanitized or \"target\"\n\n\ndef derive_repo_base_name(repo_url: str) -> str:\n    if repo_url.endswith(\"/\"):\n        repo_url = repo_url[:-1]\n\n    if \":\" in repo_url and repo_url.startswith(\"git@\"):\n        path_part = repo_url.split(\":\", 1)[1]\n    else:\n        path_part = urlparse(repo_url).path or repo_url\n\n    candidate = path_part.split(\"/\")[-1]","sourceCodeStart":1213,"sourceCodeEnd":1249,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/interface/utils.py#L1213-L1249","documentation":"Raised when the target list file was read successfully but contains zero usable targets — every line was blank or a '#' comment. Strix refuses to start a multi-target scan with an empty workload rather than exiting as a pointless clean run.","triggerScenarios":"A file containing only blank lines; all lines prefixed with '#' (e.g. everything commented out during debugging); a file of only whitespace after stripping.","commonSituations":"Commenting out all targets while testing and forgetting to restore them; template files shipped with only comments; lists generated by a previous pipeline step that produced no output.","solutions":["Uncomment or add at least one valid target line (one target per line, '#' starts a comment).","If the list is generated, verify the generator produced content: wc -l and grep -vc '^[[:space:]]*#' targets.txt.","Skip the --target-list flag entirely if you only need a single target and pass -t instead."],"exampleFix":"# targets.txt - before\n# https://example-a.com\n# https://example-b.com\n\n# targets.txt - after\nhttps://example-a.com\nhttps://example-b.com","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\nlines = [l.strip() for l in Path(path_str).read_text(encoding=\"utf-8\").splitlines()]\nusable = [l for l in lines if l and not l.startswith(\"#\")]\nif not usable:\n    raise SystemExit(f\"{path_str} has no active targets; uncomment at least one line\")\ntargets = read_target_list_file(path_str)","typeGuard":null,"tryCatchPattern":"try:\n    targets = read_target_list_file(path_str)\nexcept ValueError as e:\n    if \"is empty\" in str(e):\n        raise SystemExit(\"Target list has no uncommented lines; add targets or drop --target-list.\") from e\n    raise","preventionTips":["Lint target lists in CI: grep -cv '^[[:space:]]*#' targets.txt must be > 0","Don't leave debugging runs with everything commented out committed as the default list"],"tags":["validation","targets","configuration"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}