dagger/dagger · critical · ExceptionGroup

{download_error} failed to use CLI from PATH {cli_bin!r}: {e

Error message

{download_error}
failed to use CLI from PATH {cli_bin!r}: {e}

What it means

An ExceptionGroup raised when both the primary (downloaded CLI) and the fallback (CLI from PATH) provisioning attempts fail. The download failed earlier (download_error), and then starting/connecting to the PATH dagger binary also raised an exception. Both errors are surfaced together so the root causes aren't hidden.

Source

Thrown at sdk/python/src/dagger/provisioning/_engine.py:111

            download_error = None
            try:
                cli_bin = await self.get_cli()
            except CLIReleaseUnavailableError as e:
                download_error = e
                cli_bin = fallback_to_local_cli(e, self.cfg.log_output)

            await self.progress.update("Creating new Engine session")
            try:
                connect_params = await self.stack.enter_async_context(
                    start_cli_session(self.cfg, cli_bin)
                )
            except Exception as e:
                if download_error is not None:
                    msg = (
                        f"{download_error}\nfailed to use CLI from PATH "
                        f"{cli_bin!r}: {e}"
                    )
                    raise ExceptionGroup(msg, [download_error, e]) from e
                raise

        self.connect_params = connect_params
        self.connect_config = ConnectConfig(
            timeout=self.cfg.timeout,
            retry=self.cfg.retry,
        )

        return self

    async def get_cli(self) -> str:
        """Get path to CLI."""
        if cli_bin := os.getenv("_EXPERIMENTAL_DAGGER_CLI_BIN"):
            return cli_bin

        # Get from cache or download.
        return await Downloader(progress=self.progress)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Fix the first error in the group (the download failure) — network, proxy, or pinned version availability.
  2. Verify the PATH dagger binary runs standalone (`dagger version`); reinstall or upgrade it if it errors.
  3. Ensure the PATH CLI version is compatible with the SDK version you are using.
  4. Remove conflicting DAGGER_SESSION_* env vars so provisioning starts a fresh engine.
  5. In CI, pin a known-good dagger CLI install step so the fallback is healthy.
Defensive patterns

Strategy: fallback

Validate before calling

import shutil, subprocess
def path_cli_usable() -> bool:
    b = shutil.which("dagger")
    if not b:
        return False
    try:
        return subprocess.run([b, "version"], capture_output=True, timeout=10).returncode == 0
    except Exception:
        return False
# if not path_cli_usable(): fix the local CLI before provisioning

Try / catch

try:
    async with dagger.Connection() as client:
        ...
except ExceptionGroup as eg:
    for sub in eg.exceptions:
        logger.error("provisioning failed: %r", sub)
    raise  # fix download network AND local dagger install

Prevention

When it happens

Trigger: In provision(), after a failed download (download_error set), the code tries to start/connect using the PATH dagger binary cli_bin; any exception in that path is re-raised as ExceptionGroup([download_error, e]) with this combined message.

Common situations: Download blocked by network issues AND the PATH dagger is an incompatible/broken version that fails to start (e.g. engine version incompatibility, missing exec permission); both the pinned download and local binary unusable in restricted CI environments.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/711fb6b33be14e97. Report an issue: GitHub.