github/copilot-sdk · error · RuntimeError

Failed to read runtime package entry

Error message

Failed to read runtime package entry: {member.name}

What it means

When extracting a runtime package member, archive.extractfile() returned None despite the member passing the isfile check, so its bytes cannot be read. This is treated as a fatal extraction error since the runtime bundle would be silently incomplete.

Solutions

  1. Delete the cached download and retry so the archive is fetched fresh.
  2. Verify the archive integrity manually (gzip -t, tar -tf).
  3. Check available disk space and memory for the extraction destination.
  4. Report the release if corruption reproduces from the official source.
Defensive patterns

Strategy: retry

Validate before calling

import gzip
gzip.open("pkg.tgz").close()  # raises on corruption before extraction

Try / catch

import shutil
try:
    ensure_runtime_wrapper()
except RuntimeError as e:
    if "Failed to read runtime package entry" in str(e):
        clear_cache(); ensure_runtime_wrapper(force=True)
    else:
        raise

Prevention

When it happens

Trigger: A tar member reports isfile() but its data stream cannot be opened — typically corrupt/truncated archives or exotic member metadata that tarfile cannot materialize.

Common situations: Interrupted or corrupted downloads (rare, since checksums are verified first); very large members with stream issues; malformed tar metadata.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/9b8516a04fafc338. Report an issue: GitHub.

Appendix: source

Thrown at python/copilot/_cli_download.py:313

        relative = relative[2:]
    destination = Path(*relative)
    if destination.is_absolute() or ".." in destination.parts:
        raise RuntimeError(f"Unsafe runtime package path: {member_name}")
    return destination


def _materialize_runtime_bundle(data: bytes, runtime_platform: str, destination: Path) -> None:
    """Extract the hostless runtime tree, retaining unknown package assets by default."""
    with tarfile.open(fileobj=io.BytesIO(data), mode="r:gz") as archive:
        for member in archive:
            relative = _hostless_runtime_path(member.name, runtime_platform)
            if relative is None or member.isdir():
                continue
            if not member.isfile():
                raise RuntimeError(f"Unsupported runtime package entry: {member.name}")
            extracted = archive.extractfile(member)
            if extracted is None:
                raise RuntimeError(f"Failed to read runtime package entry: {member.name}")
            target = destination / relative
            target.parent.mkdir(parents=True, exist_ok=True)
            target.write_bytes(extracted.read())
            if sys.platform != "win32":
                target.chmod(member.mode & 0o777)


def ensure_runtime_wrapper(version: str | None = None, force: bool = False) -> str:
    """Provision the runtime pair and retained assets from the release package."""
    ver = version or CLI_VERSION
    if not ver:
        raise RuntimeError("No runtime version is pinned.")
    runtime_platform = get_runtime_platform()
    wrapper_name = "copilot-runtime.exe" if sys.platform == "win32" else "copilot-runtime"
    pair_dir = get_cache_dir(ver) / "prebuilds" / runtime_platform
    wrapper_path = pair_dir / wrapper_name
    runtime_path = pair_dir / "runtime.node"
    assets_marker = pair_dir / _HOSTLESS_ASSETS_MARKER

View on GitHub (pinned to cd8cf15dc3)