unslothai/unsloth · error · RuntimeError

The prepared {spec.name} runtime failed integrity validation

Error message

The prepared {spec.name} runtime failed integrity validation

What it means

Final self-check in _install_runtime: after copying sources and writing generated files into staging, _valid_runtime(staging, spec, checkout) re-validates the assembled tree (including runtime_tree_digest); failure aborts before _replace_owned_directory promotes it. It guarantees an installed runtime is never promoted unless it byte-for-byte matches the pinned runtime digest.

Source

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

        if spec.source_tree_digest is not None:
            source_manifest = _sealed_source_manifest(checkout, spec)
            if source_manifest is None:
                raise RuntimeError(f"The cached {spec.name} source failed integrity validation")
        else:
            source_manifest = _checkout_manifest(checkout, spec)
        for relative, expected_digest in source_manifest.items():
            source_file = checkout / relative
            destination_file = staging / relative
            destination_file.parent.mkdir(parents = True, exist_ok = True)
            shutil.copy2(source_file, destination_file)
            if hashlib.sha256(destination_file.read_bytes()).hexdigest() != expected_digest:
                raise RuntimeError(f"{spec.name} source changed while preparing its runtime")
        for relative, content in _generated_file_contents(spec).items():
            destination_file = staging / relative
            destination_file.parent.mkdir(parents = True, exist_ok = True)
            destination_file.write_bytes(content)
        if not _valid_runtime(staging, spec, checkout):
            raise RuntimeError(f"The prepared {spec.name} runtime failed integrity validation")
        _replace_owned_directory(staging, runtime)
    finally:
        _remove_owned_path(workspace)


def ensure_pinned_source(
    spec: PinnedSource, *, legacy_sources: tuple[Path | str, ...] = ()
) -> Path:
    revision = spec.revision.lower()
    if _REVISION_PATTERN.fullmatch(revision) is None or revision != spec.revision:
        raise RuntimeError(f"{spec.name} source revision must be a lowercase full Git commit")
    for digest in (spec.source_tree_digest, spec.runtime_tree_digest):
        if digest is not None and _SHA256_PATTERN.fullmatch(digest) is None:
            raise RuntimeError(f"{spec.name} source digest must be a lowercase SHA-256")
    if (spec.source_tree_digest is None) != (spec.runtime_tree_digest is None):
        raise RuntimeError(f"{spec.name} source and runtime digests must be configured together")

    parent = cache_root() / "third-party-sources" / spec.name

View on GitHub (pinned to 203007d190)

Solutions

  1. Recompute runtime_tree_digest from a known-good assembled runtime and update the pin (keeping the paired source/runtime digests in sync)
  2. Check free space and permissions on the cache volume — a silently skipped write fails validation
  3. Purge the spec's cache slice and retry to eliminate a corrupted intermediate
  4. If it persists on a clean cache, the pin's digests and the library's _generated_file_contents are inconsistent — regenerate both digests with the same library version
Defensive patterns

Strategy: validation

Validate before calling

# regenerate digests with the same library version that will validate them
from studio.backend.utils import third_party_source as tps
assert spec.runtime_tree_digest == tps.compute_runtime_digest(assembled_runtime_dir), (
    "runtime digest stale — re-pin before deploying"
)

Try / catch

try:
    ensure_pinned_source(spec)
except RuntimeError as e:
    if "prepared" in str(e) and "runtime" in str(e):
        # purge cache and retry once; persistent failure means stale runtime_tree_digest in the pin

Prevention

When it happens

Trigger: The assembled staging runtime fails _valid_runtime — generated file contents (_generated_file_contents) don't match what the runtime digest was pinned against, the manifest copy is incomplete, or runtime_tree_digest in the spec is stale relative to the code that generates runtime files.

Common situations: Library upgrade changed generated runtime files but the pin's runtime_tree_digest was not recomputed; mismatched pair where source_tree_digest is current but runtime_tree_digest is from an older revision; filesystem issues dropping a file during staging.

Related errors


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