oraios/serena · critical · SolidLSPException

Checksum verification failed for '{file_path}': expected {ex

Error message

Checksum verification failed for '{file_path}': expected {expected_sha256}, got {actual_sha256}

What it means

Raised by FileUtils._verify_sha256_if_configured after a verified download: the SHA-256 of the downloaded file does not match the configured expected hash. This is a safety check ensuring the language-server artifact was not corrupted or tampered with in transit.

Source

Thrown at src/solidlsp/ls_utils.py:572

        Calculates the SHA256 checksum of a file.
        """
        sha256_hash = hashlib.sha256()
        with open(file_path, "rb") as input_file:
            for chunk in iter(lambda: input_file.read(8192), b""):
                sha256_hash.update(chunk)
        return sha256_hash.hexdigest()

    @staticmethod
    def _verify_sha256_if_configured(file_path: str, expected_sha256: str | None) -> None:
        """
        Verifies the SHA256 checksum of a file when an expected value is provided.
        """
        if expected_sha256 is None:
            return

        actual_sha256 = FileUtils.calculate_sha256(file_path)
        if actual_sha256.lower() != expected_sha256.lower():
            raise SolidLSPException(f"Checksum verification failed for '{file_path}': expected {expected_sha256}, got {actual_sha256}")

    @staticmethod
    def _validate_download_host(url: str, allowed_hosts: Sequence[str] | None) -> None:
        """
        Validates that a download URL resolves to one of the configured hosts.
        """
        if not allowed_hosts:
            return

        hostname = urlparse(url).hostname
        normalized_allowed_hosts = {host.lower() for host in allowed_hosts}
        if hostname is None or hostname.lower() not in normalized_allowed_hosts:
            raise SolidLSPException(
                f"Refusing to download from host '{hostname or '<unknown>'}'; allowed hosts: {sorted(normalized_allowed_hosts)}"
            )

    @staticmethod
    def _validate_extraction_path(member_name: str, target_path: str) -> str:

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Recompute the artifact hash upstream and update the configured expected_sha256 to the new official value
  2. Re-download the file; transient truncation produces wrong hashes
  3. Verify you downloaded the exact variant (arch/OS) the hash was computed for

Example fix

// before
expected_sha256 = "abc123..."  # stale pin
// after
expected_sha256 = sha256sum(language_server.zip)  # refreshed from release notes
Defensive patterns

Strategy: validation

Validate before calling

import hashlib
actual = hashlib.sha256(open(path, "rb").read()).hexdigest()
if actual.lower() != expected_sha256.lower():
    raise ValueError(f"pre-download checksum mismatch: {actual}")

Try / catch

try:
    download_file_verified(url, path, expected_sha256=expected)
except SolidLSPException as e:
    if "Checksum verification failed" in str(e):
        refresh_expected_hash_from_release_notes()  # or fail hard
    raise

Prevention

When it happens

Trigger: download_file_verified invoked with an expected_sha256 that does not match the actual file, e.g. the upstream artifact was updated/rebuilt while a pinned hash is stale, or the download was truncated.

Common situations: Pinned checksums in config go stale after upstream releases a new build; CDN serves a different variant (e.g. different architecture); proxy injects content.

Related errors


AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29). Data as JSON: /api/errors/de4059fdeb9ef88f. Report an issue: GitHub.