unslothai/unsloth · critical · RuntimeError

The pinned {spec.name} archive contains a non-regular file

Error message

The pinned {spec.name} archive contains a non-regular file

What it means

During member iteration, any entry that is neither a directory nor a regular file (symlink, device, fifo, hardlink) — or a regular file with a negative size — is rejected before extraction. Extraction code only ever calls open('wb') and copy loops, so irregular members must never reach it; this blocks symlink/hardlink attacks where a later file write would follow a link out of the staging tree.

Source

Thrown at studio/backend/utils/third_party_source.py:657

        member_count = 0
        uncompressed_bytes = 0
        extracted = set()
        try:
            with archive.open("rb") as compressed:
                with gzip.GzipFile(fileobj = compressed, mode = "rb") as decompressed:
                    reader = _BoundedArchiveReader(decompressed, _ARCHIVE_MAX_TAR_BYTES)
                    with tarfile.open(fileobj = reader, mode = "r|") as bundle:
                        for member in bundle:
                            member_count += 1
                            if member_count > _ARCHIVE_MAX_MEMBERS:
                                raise RuntimeError(
                                    f"The pinned {spec.name} archive has too many entries"
                                )
                            parts = _archive_member_parts(member, spec)
                            if member.isdir():
                                continue
                            if not member.isfile() or member.size < 0:
                                raise RuntimeError(
                                    f"The pinned {spec.name} archive contains a non-regular file"
                                )
                            uncompressed_bytes += member.size
                            if uncompressed_bytes > _ARCHIVE_MAX_UNCOMPRESSED_BYTES:
                                raise RuntimeError(
                                    f"The pinned {spec.name} archive expands too large"
                                )
                            if len(parts) < 3 or parts[1] != spec.package:
                                continue
                            relative = "/".join(parts[1:])
                            _package_path_parts(relative, spec, kind = "archive")
                            if relative in extracted:
                                raise RuntimeError(
                                    f"The pinned {spec.name} archive contains duplicate files"
                                )
                            extracted.add(relative)
                            source_file = bundle.extractfile(member)
                            if source_file is None:

View on GitHub (pinned to 203007d190)

Solutions

  1. List entry types: tar -tvzf source.tar.gz | grep -v '^[-d]' to find symlinks/devices in the archive
  2. Repack the source without symlinks (dereference with tar --dereference / cp -rL) and re-pin digests
  3. Use the canonical codeload tarball for the revision — GitHub source archives do not contain device nodes; if they contain symlinks, this pin cannot be used and needs a sanitized mirror
  4. If tampering is suspected (digest mismatch), treat as security incident

Example fix

# repack without symlinks, then re-pin
# tar --dereference -czf clean.tar.gz foo-<sha>/
PinnedSource(..., source_tree_digest=recompute_digest(clean_tree))
Defensive patterns

Strategy: validation

Validate before calling

import tarfile
with tarfile.open("source.tar.gz") as tf:
    for m in tf:
        if not (m.isdir() or m.isfile()) or m.size < 0:
            raise SystemExit(f"irregular member rejected: {m.name} type={m.type}")

Type guard

def archive_members_regular(archive: Path) -> bool:
    with tarfile.open(archive) as tf:
        return all(m.isdir() or (m.isfile() and m.size >= 0) for m in tf)

Try / catch

try:
    ensure_pinned_source(spec)
except RuntimeError as e:
    if "non-regular file" in str(e):
        # repack with tar --dereference and re-pin digests

Prevention

When it happens

Trigger: Archive contains a tar symlink entry (e.g. `pkg/lib -> /usr/lib`), a char/block device, a FIFO, or a member with size < 0 inside the target package subtree. Encountered when iterating a member that is not member.isdir() and fails member.isfile().

Common situations: Archives created on systems that preserve symlinks (many repos symlink docs/licenses); malicious archives planting symlinks to overwrite system files via later extraction; corrupt tar headers producing nonsense types/sizes.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/cc43fbd006ff00e3. Report an issue: GitHub.