oraios/serena · error · RuntimeError

SHA256 checksum mismatch for vshaxe VSIX. Expected {expected

Error message

SHA256 checksum mismatch for vshaxe VSIX. Expected {expected_sha}, got {sha256.hexdigest()}. The file may be corrupted or tampered with.

What it means

Serena verifies the SHA256 checksum of the vshaxe VSIX downloaded from Open VSX against an expected hash. If the digest of the downloaded file differs, the file is deleted and this RuntimeError is raised to prevent installing a corrupted or tampered binary.

Source

Thrown at src/solidlsp/language_servers/haxe_language_server.py:155

        def _download_from_open_vsx(cls, target_dir: str, version: str) -> str | None:
            """Download a vshaxe VSIX from Open VSX and extract server.js.
            Verifies the download against a hardcoded SHA256 checksum when using the default version.
            """
            try:
                download_url = f"https://open-vsx.org/api/nadako/vshaxe/{version}/file/nadako.vshaxe-{version}.vsix"
                log.info("Downloading Haxe Language Server v%s from Open VSX...", version)
                vsix_path = os.path.join(tempfile.gettempdir(), "vshaxe.vsix")
                urllib.request.urlretrieve(download_url, vsix_path)

                # Verify SHA256 checksum only when the resolved version is one of our pinned ones (INITIAL or current DEFAULT)
                expected_sha = _vshaxe_sha(version)
                if expected_sha is not None:
                    sha256 = hashlib.sha256()
                    with open(vsix_path, "rb") as f:
                        for chunk in iter(lambda: f.read(8192), b""):
                            sha256.update(chunk)
                    if sha256.hexdigest().lower() != expected_sha:
                        os.remove(vsix_path)
                        raise RuntimeError(
                            f"SHA256 checksum mismatch for vshaxe VSIX. Expected {expected_sha}, "
                            f"got {sha256.hexdigest()}. The file may be corrupted or tampered with."
                        )
                    log.info("SHA256 checksum verified")
                else:
                    log.info("Using custom version %s — skipping SHA256 verification", version)

                # VSIX files are ZIP archives — extract bin/ contents
                bin_dir = os.path.join(target_dir, "bin")
                os.makedirs(bin_dir, exist_ok=True)
                with zipfile.ZipFile(vsix_path, "r") as zf:
                    for entry in zf.namelist():
                        if "/bin/" in entry:
                            filename = entry.split("/bin/", 1)[-1]
                            if filename and ".." not in filename:
                                dest_path = os.path.join(bin_dir, filename)
                                os.makedirs(os.path.dirname(dest_path), exist_ok=True)

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Delete any partially downloaded VSIX and retry the download (transient network corruption is the most common cause).
  2. Verify the actual checksum: sha256sum of the downloaded VSIX and compare with the expected hash baked into the code/config.
  3. If Open VSX published a new vshaxe release, update the expected_sha (or pinned version + hash) in the code.
  4. Check for corporate proxy/MITM interference and retry from an unrestricted network.

Example fix

# before (stale pinned hash for an old VSIX)
expected_sha = "9f2c...old"
# after (hash of the current release)
# sha256sum vshaxe-*.vsix
expected_sha = "4ab1...new"
Defensive patterns

Strategy: validation

Validate before calling

import hashlib, pathlib
def validate_vsix(path: str, expected_sha: str) -> bool:
    p = pathlib.Path(path)
    if not p.is_file() or p.stat().st_size == 0:
        return False
    h = hashlib.sha256()
    with p.open("rb") as f:
        for chunk in iter(lambda: f.read(8192), b""):
            h.update(chunk)
    return h.hexdigest().lower() == expected_sha.lower()

Try / catch

try:
    path = get_or_install_haxe_ls()
except RuntimeError as e:
    if "checksum mismatch" in str(e):
        retry_download_with_backoff()  # file already deleted by library
    else:
        raise

Prevention

When it happens

Trigger: _get_or_install_core_dependency calls _download_from_open_vsx; the downloaded VSIX's sha256 hexdigest (lowercased) does not equal expected_sha, so the guard `sha256.hexdigest().lower() != expected_sha` fires and raises before the language server can be started.

Common situations: Interrupted or proxied downloads producing truncated files; CDN/Open VSX serving an updated VSIX version while the code pins an old expected hash; corporate TLS-inspecting proxies rewriting payloads; disk corruption in the temp/install directory.

Related errors


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