usestrix/strix · error · ValueError

Invalid path: {target} - {e!s}

Error message

Invalid path: {target} - {e!s}

What it means

Wraps OSError/RuntimeError raised while inspecting the target path (existence checks, is_dir, resolve, or check_mountable_dir) into a ValueError with context. This is a fail-fast wrapper: the original exception is chained via 'from e', so the underlying filesystem problem (permission denied, broken symlink loops, I/O errors) is preserved in the cause.

Source

Thrown at strix/interface/utils.py:1177

        pass
    else:
        return "ip_address", {"target_ip": str(ip_obj)}

    path = Path(target).expanduser()
    try:
        if path.exists():
            if path.is_dir():
                check_mountable_dir(path)
                return "local_code", {"target_path": str(path.resolve())}
            spec_format = detect_spec_format(path)
            if spec_format is not None:
                return "api_spec", {
                    "target_spec": str(path.resolve()),
                    "spec_format": spec_format,
                }
            raise ValueError(f"Path exists but is not a directory: {target}")
    except (OSError, RuntimeError) as e:
        raise ValueError(f"Invalid path: {target} - {e!s}") from e

    if target.endswith(".git"):
        return "repository", {"target_repo": target}

    if "/" in target:
        host_part, _, path_part = target.partition("/")
        if "." in host_part and not host_part.startswith(".") and path_part:
            full_url = f"https://{target}"
            if _is_http_git_repo(full_url):
                return "repository", {"target_repo": full_url}
            return "web_application", {"target_url": full_url}

    if "." in target and "/" not in target and not target.startswith("."):
        parts = target.split(".")
        if len(parts) >= 2 and all(p and p.strip() for p in parts):
            return "web_application", {"target_url": f"https://{target}"}

    raise ValueError(

View on GitHub (pinned to 8551339130)

Solutions

  1. Check the underlying cause in the traceback (the 'from e' chain) to see the real OS error.
  2. Fix permissions or remount the filesystem: ls -ld <path> and retry after access is restored.
  3. Copy or move the code to a stable local directory and target that.
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path

def is_readable_path(target: str) -> bool:
    try:
        p = Path(target).expanduser()
        return p.exists() and (p.is_dir() or p.is_file())
    except OSError:
        return False

if not is_readable_path(target):
    raise SystemExit(f"Target path is not accessible: {target}")

Try / catch

try:
    ttype, details = infer_target_type(target)
except ValueError as e:
    if str(e).startswith("Invalid path:"):
        raise SystemExit(f"Filesystem problem with {target!r}: check mounts and permissions ({e})") from e
    raise

Prevention

When it happens

Trigger: Target path on an unreadable mount, permission-denied directory in stat/resolve, a symlink loop (RuntimeError from resolve(strict=False) is rare but OSError ELOOP is common), or check_mountable_dir raising on an OS error during Path.resolve() of symlinked system dirs.

Common situations: Scanning paths on network mounts that dropped; docker volume paths with odd permissions; macOS /private symlink edge cases; paths on drives removed between check and use.

Related errors


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/1ec6b437601ab795. Report an issue: GitHub.