HKUDS/nanobot · error · CliAppError

pip is not available and uv is not installed

Error message

pip is not available and uv is not installed

What it means

Environment-capability failure in CliAppService._pip_install_argv: the app's strategy requires a pip install, but `pip` is not importable in the current interpreter and no `uv` executable is on PATH, so there is no way to build the install/uninstall argv. Raised as CliAppError; remediate by installing pip or uv.

Solutions

  1. Install pip into the running environment (e.g. ensurepip)
  2. Install uv and ensure it is on PATH
  3. Install the CLI app manually with its documented install command
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at nanobot/apps/cli/service.py:870 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of HKUDS/nanobot@42f37dc4c0 (2026-08-26). Data as JSON: /api/errors/17efe81e2457144b. Report an issue: GitHub.

Appendix: source

Thrown at nanobot/apps/cli/service.py:870

    def _pip_available() -> bool:
        """Return True if pip is importable for the current interpreter."""
        from importlib.util import find_spec

        return find_spec("pip") is not None

    def _pip_install_argv(self, app: dict[str, Any], *, update: bool = False) -> list[str]:
        install_cmd = str(app.get("install_cmd") or "")
        if not _is_pip_install_command(install_cmd) or _has_shell_meta(install_cmd):
            raise CliAppError("unsupported pip install command")
        tokens = shlex.split(install_cmd)
        args = tokens[2:] if tokens[:2] == ["pip", "install"] else tokens[4:]
        pip_available = self._pip_available()
        if pip_available:
            prefix = [sys.executable, "-m", "pip", "install"]
        elif shutil.which("uv"):
            prefix = ["uv", "pip", "install", "--python", sys.executable]
        else:
            raise CliAppError("pip is not available and uv is not installed")
        if update:
            if pip_available:
                prefix.extend(["--upgrade", "--force-reinstall"])
            else:
                prefix.extend(["--upgrade", "--reinstall"])
        return prefix + args

    def _pip_uninstall_argv(
        self,
        app: dict[str, Any],
        installed_entry: dict[str, Any] | None = None,
    ) -> list[str]:
        if self._pip_available():
            prefix = [sys.executable, "-m", "pip", "uninstall", "-y"]
        elif shutil.which("uv"):
            prefix = ["uv", "pip", "uninstall", "--python", sys.executable]
        else:
            raise CliAppError("pip is not available and uv is not installed")

View on GitHub (pinned to 42f37dc4c0)