{"record":{"id":"8491039b1073c36d","repo":"usestrix/strix","slug":"refusing-to-mount-resolved-into-the-sandbox-i","errorCode":null,"errorMessage":"Refusing to mount '{resolved}' into the sandbox: it is a system or home directory, not a codebase. Point the target at the project directory you want tested.","messagePattern":"Refusing to mount '(.+?)' into the sandbox: it is a system or home directory, not a codebase\\. Point the target at the project directory you want tested\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strix/interface/utils.py","lineNumber":1406,"sourceCode":"        raise ValueError(f\"'{path}' is not an existing directory.\")\n\n    # Both the literal and the resolved form: macOS reaches /etc through the\n    # /private/etc symlink, and only the resolved path is compared below.\n    exact = {str(Path(root)).casefold() for root in _FORBIDDEN_MOUNT_ROOTS}\n    exact |= {str(Path(root).resolve()).casefold() for root in _FORBIDDEN_MOUNT_ROOTS}\n    exact.add(str(Path.home().resolve()).casefold())\n    tree_roots = set(_FORBIDDEN_MOUNT_TREES)\n    if os.name == \"nt\":\n        drive = Path(resolved.anchor)\n        tree_roots |= {str(drive / name) for name in _FORBIDDEN_WINDOWS_TREE_NAMES}\n        exact.add(str(drive / \"Users\").casefold())\n    trees = [Path(root) for root in tree_roots] + [Path(root).resolve() for root in tree_roots]\n    if (\n        str(resolved).casefold() in exact\n        or resolved.parent == resolved\n        or any(_is_within(resolved, tree) for tree in trees)\n    ):\n        raise ValueError(\n            f\"Refusing to mount '{resolved}' into the sandbox: it is a system \"\n            \"or home directory, not a codebase. Point the target at the \"\n            \"project directory you want tested.\"\n        )\n\n    credential = next(\n        (part for part in resolved.parts if part.casefold() in _FORBIDDEN_MOUNT_DIR_NAMES), None\n    )\n    if credential is not None:\n        raise ValueError(\n            f\"Refusing to mount '{resolved}' into the sandbox: '{credential}' \"\n            \"holds credentials, not code.\"\n        )\n\n\ndef dedupe_local_targets(targets_info: list[dict[str, Any]]) -> list[dict[str, Any]]:\n    result: list[dict[str, Any]] = []\n    seen_paths: set[str] = set()","sourceCodeStart":1388,"sourceCodeEnd":1424,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/interface/utils.py#L1388-L1424","documentation":"A safety guard that refuses to mount system or home directories into the Docker sandbox. The resolved path is rejected if it equals a forbidden root ('/', '/var', '/opt', '/home', '/root', '/Users', '/Volumes', plus resolved forms and the user's home), is a filesystem root, or lies within a forbidden tree (/etc, /usr, /bin, /Applications, /System, Windows/Program Files, etc.). Rationale: mounting those exposes the OS and personal files to the scanner container.","triggerScenarios":"Running strix -t / or -t ~/my-project (home dir itself is forbidden); -t /etc, -t /Applications/some.app, -t 'C:\\Program Files', -t /opt/tool; any path that resolves under one of the forbidden trees or equals home().","commonSituations":"Trying to scan 'everything' with -t ~ or -t /; putting a project inside /opt or /Applications and targeting that prefix; running as root with repos under /root; targeting a mounted volume under /Volumes on macOS.","solutions":["Target the specific project directory, e.g. ~/projects/app not ~ itself.","If the project lives under a forbidden tree (/opt, /Applications), copy or clone it to a normal location like ~/code and scan that.","Do not use /, /home, /Users, /var, /opt, /root, /Volumes, /etc, /usr (or Windows system dirs) as scan targets."],"exampleFix":"# before\nstrix -n -t ~                 # home directory refused\n\n# after\nstrix -n -t ~/projects/my-app  # actual codebase directory","handlingStrategy":"validation","validationCode":"from pathlib import Path\nimport os\n\nFORBIDDEN_ROOTS = {\"/\", \"/private\", \"/var\", \"/opt\", \"/home\", \"/root\", \"/srv\", \"/users\", \"/volumes\"}\nFORBIDDEN_TREES = (\"/bin\", \"/sbin\", \"/usr\", \"/etc\", \"/lib\", \"/lib64\", \"/nix/store\",\n                    \"/run/current-system/sw\", \"/applications\", \"/library\", \"/system\",\n                    \"/dev\", \"/boot\", \"/proc\", \"/sys\")\n\ndef is_safe_mount_dir(path: str) -> bool:\n    resolved = Path(path).resolve()\n    r = str(resolved).casefold()\n    if r in FORBIDDEN_ROOTS or r == str(Path.home().resolve()).casefold():\n        return False\n    if resolved.parent == resolved:\n        return False\n    return not any(r.startswith(t) for t in FORBIDDEN_TREES)\n\nif not is_safe_mount_dir(target):\n    raise SystemExit(f\"{target} is a system/home directory; target the project dir instead\")","typeGuard":"def is_specific_project_dir(path: str) -> bool:\n    from pathlib import Path\n    resolved = Path(path).resolve()\n    return resolved.is_dir() and resolved != Path.home().resolve() and len(resolved.parts) > 2 and not str(resolved).startswith(('/usr', '/etc', '/bin', '/Applications', '/System'))","tryCatchPattern":"try:\n    check_mountable_dir(Path(target))\nexcept ValueError as e:\n    if \"system or home directory\" in str(e):\n        raise SystemExit(\"Strix refuses system/home mounts. Point -t at the project subdirectory.\") from e\n    raise","preventionTips":["Never pass /, ~, /home, /opt, /etc, /Applications, or drive roots as scan targets","Keep source code in a dedicated projects directory and scan that exact folder"],"tags":["sandbox","docker","security","filesystem"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}