{"record":{"id":"997b11129760295f","repo":"usestrix/strix","slug":"path-exists-but-is-not-a-directory-target","errorCode":null,"errorMessage":"Path exists but is not a directory: {target}","messagePattern":"Path exists but is not a directory: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strix/interface/utils.py","lineNumber":1175,"sourceCode":"        ip_obj = ipaddress.ip_address(target)\n    except ValueError:\n        pass\n    else:\n        return \"ip_address\", {\"target_ip\": str(ip_obj)}\n\n    path = Path(target).expanduser()\n    try:\n        if path.exists():\n            if path.is_dir():\n                check_mountable_dir(path)\n                return \"local_code\", {\"target_path\": str(path.resolve())}\n            spec_format = detect_spec_format(path)\n            if spec_format is not None:\n                return \"api_spec\", {\n                    \"target_spec\": str(path.resolve()),\n                    \"spec_format\": spec_format,\n                }\n            raise ValueError(f\"Path exists but is not a directory: {target}\")\n    except (OSError, RuntimeError) as e:\n        raise ValueError(f\"Invalid path: {target} - {e!s}\") from e\n\n    if target.endswith(\".git\"):\n        return \"repository\", {\"target_repo\": target}\n\n    if \"/\" in target:\n        host_part, _, path_part = target.partition(\"/\")\n        if \".\" in host_part and not host_part.startswith(\".\") and path_part:\n            full_url = f\"https://{target}\"\n            if _is_http_git_repo(full_url):\n                return \"repository\", {\"target_repo\": full_url}\n            return \"web_application\", {\"target_url\": full_url}\n\n    if \".\" in target and \"/\" not in target and not target.startswith(\".\"):\n        parts = target.split(\".\")\n        if len(parts) >= 2 and all(p and p.strip() for p in parts):\n            return \"web_application\", {\"target_url\": f\"https://{target}\"}","sourceCodeStart":1157,"sourceCodeEnd":1193,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/interface/utils.py#L1157-L1193","documentation":"Raised by infer_target_type when the target path exists on disk but is neither a directory nor a recognizable API spec file. Strix happily accepts existing directories as local code and files detected by detect_spec_format (OpenAPI/Swagger/Postman); any other existing file — a README, a random .txt, a lockfile — falls through to this error.","triggerScenarios":"infer_target_type('./notes.txt') where notes.txt exists but is not OpenAPI JSON/YAML or a Postman collection; pointing -t at a symlink to a regular file of an unsupported type; a directory path that actually resolves to a file.","commonSituations":"Typo where the user meant the parent directory but hit a file inside it; expecting any file to be scanned as 'local code' (Strix only takes directories for that); an export that produced a .yaml that is not actually an OpenAPI document, so detect_spec_format returns None.","solutions":["Point -t at the project directory containing the code instead of an individual file.","If the file is meant to be an API spec, verify it is valid OpenAPI/Swagger (.json/.yaml with openapi/swagger field) or a Postman collection export.","Rename/re-export the spec so its format is detectable, or wrap single files in a directory."],"exampleFix":"# before\nstrix -n -t ./openapi-export.txt   # exists but not a recognized spec\n\n# after\nstrix -n -t ./openapi-export.json  # valid OpenAPI document","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\np = Path(target).expanduser()\nif p.exists() and not p.is_dir():\n    # only spec files are accepted as files\n    if p.suffix.lower() not in {\".json\", \".yaml\", \".yml\"}:\n        target = str(p.parent)  # scan the containing project directory instead","typeGuard":"from strix.interface.utils import detect_spec_format\n\ndef is_acceptable_file_target(p: Path) -> bool:\n    return p.is_file() and detect_spec_format(p) is not None","tryCatchPattern":"try:\n    ttype, details = infer_target_type(target)\nexcept ValueError as e:\n    if \"not a directory\" in str(e):\n        ttype, details = infer_target_type(str(Path(target).expanduser().parent))\n    else:\n        raise","preventionTips":["Point scans at directories for code and reserve file targets for OpenAPI/Postman specs","Validate spec files with a YAML/JSON OpenAPI linter before scanning"],"tags":["targets","filesystem","validation","api-spec"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}