zed-industries/zed · error · ValueError
archive links are not supported: {member.name}
Error message
archive links are not supported: {member.name} What it means
safe_extract_archive() deliberately refuses tar members that are symlinks or hardlinks (member.issym()/islnk()). Links are the classic vehicle for tar-extraction attacks — a link pointing outside the destination with a later member writing through it — so the helper rejects any archive containing them rather than trying to resolve them safely.
Source
Thrown at crates/eval_cli/zed_eval/common.py:48
def write_json(path: pathlib.Path, data: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n")
def load_json(path: pathlib.Path) -> dict[str, Any] | None:
try:
data = json.loads(path.read_text())
except (OSError, json.JSONDecodeError):
return None
return data if isinstance(data, dict) else None
def safe_extract_archive(archive: tarfile.TarFile, destination: pathlib.Path) -> None:
destination = destination.resolve()
members = archive.getmembers()
for member in members:
if member.issym() or member.islnk():
raise ValueError(f"archive links are not supported: {member.name}")
target = (destination / member.name).resolve()
if destination != target and destination not in target.parents:
raise ValueError(f"archive member escapes destination: {member.name}")
archive.extractall(destination, members=members)
def command_exists(name: str) -> bool:
return shutil.which(name) is not None
def run_command(
command: list[str], *, capture: bool = False
) -> subprocess.CompletedProcess[str]:
return subprocess.run(command, check=True, text=True, capture_output=capture)
def dedupe_preserving_order(values: list[str]) -> list[str]:
seen = set()View on GitHub (pinned to bc538def45)
Solutions
- Repack with dereferenced files: `tar --dereference --hard-dereference -czf bundle.tar.gz dir/`
- Remove incidental links from the source tree before packing
- If links are essential, extract manually after reviewing every link target
Example fix
# before tar czf bundle.tar.gz repo/ # symlinks preserved → ValueError # after tar --dereference --hard-dereference -czf bundle.tar.gz repo/
Defensive patterns
Strategy: validation
Validate before calling
import tarfile
with tarfile.open(archive_path) as archive:
links = [m.name for m in archive.getmembers() if m.issym() or m.islnk()]
if links:
raise SystemExit(f"archive contains links: {links[:5]}; repack with tar --dereference") Type guard
import tarfile
def is_link_free(members):
return not any(m.issym() or m.islnk() for m in members) Try / catch
try:
safe_extract_archive(archive, destination)
except ValueError as e:
raise SystemExit(f"unsafe archive rejected: {e}") Prevention
- Create bundles with tar -h (--dereference) and --hard-dereference
- Always extract through safe_extract_archive instead of bare extractall
- Treat link members in incoming archives as suspicious by default
When it happens
Trigger: Extracting an archive created with plain `tar czf` over a tree containing symlinks (node_modules, doc-compression links, linked repo assets) or hardlinks (nix store, pnpm content-addressed stores) — the links become members and trip the check.
Common situations: Bundling dependency trees or repo snapshots with links; archives produced on systems that hardlink duplicate files; hand-rolled packaging scripts.
Related errors
- archive member escapes destination: {member.name}
- eval-cli binary not found at {binary}. Build it with: cargo
- No eval-cli binary provided. Either pass binary_path=/path/t
- Could not detect a working directory in the container. Set E
- unknown benchmark '{benchmark_id}' (valid: {valid})
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/a4d807a0e8a7e71a.
Report an issue: GitHub.