{"record":{"id":"9ed1df2b69e61b49","repo":"oraios/serena","slug":"sha256-checksum-mismatch-for-vshaxe-vsix-expected","errorCode":null,"errorMessage":"SHA256 checksum mismatch for vshaxe VSIX. Expected {expected_sha}, got {sha256.hexdigest()}. The file may be corrupted or tampered with.","messagePattern":"SHA256 checksum mismatch for vshaxe VSIX\\. Expected (.+?), got (.+?)\\. The file may be corrupted or tampered with\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/solidlsp/language_servers/haxe_language_server.py","lineNumber":155,"sourceCode":"        def _download_from_open_vsx(cls, target_dir: str, version: str) -> str | None:\n            \"\"\"Download a vshaxe VSIX from Open VSX and extract server.js.\n            Verifies the download against a hardcoded SHA256 checksum when using the default version.\n            \"\"\"\n            try:\n                download_url = f\"https://open-vsx.org/api/nadako/vshaxe/{version}/file/nadako.vshaxe-{version}.vsix\"\n                log.info(\"Downloading Haxe Language Server v%s from Open VSX...\", version)\n                vsix_path = os.path.join(tempfile.gettempdir(), \"vshaxe.vsix\")\n                urllib.request.urlretrieve(download_url, vsix_path)\n\n                # Verify SHA256 checksum only when the resolved version is one of our pinned ones (INITIAL or current DEFAULT)\n                expected_sha = _vshaxe_sha(version)\n                if expected_sha is not None:\n                    sha256 = hashlib.sha256()\n                    with open(vsix_path, \"rb\") as f:\n                        for chunk in iter(lambda: f.read(8192), b\"\"):\n                            sha256.update(chunk)\n                    if sha256.hexdigest().lower() != expected_sha:\n                        os.remove(vsix_path)\n                        raise RuntimeError(\n                            f\"SHA256 checksum mismatch for vshaxe VSIX. Expected {expected_sha}, \"\n                            f\"got {sha256.hexdigest()}. The file may be corrupted or tampered with.\"\n                        )\n                    log.info(\"SHA256 checksum verified\")\n                else:\n                    log.info(\"Using custom version %s — skipping SHA256 verification\", version)\n\n                # VSIX files are ZIP archives — extract bin/ contents\n                bin_dir = os.path.join(target_dir, \"bin\")\n                os.makedirs(bin_dir, exist_ok=True)\n                with zipfile.ZipFile(vsix_path, \"r\") as zf:\n                    for entry in zf.namelist():\n                        if \"/bin/\" in entry:\n                            filename = entry.split(\"/bin/\", 1)[-1]\n                            if filename and \"..\" not in filename:\n                                dest_path = os.path.join(bin_dir, filename)\n                                os.makedirs(os.path.dirname(dest_path), exist_ok=True)","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/solidlsp/language_servers/haxe_language_server.py#L137-L173","documentation":"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.","triggerScenarios":"_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.","commonSituations":"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.","solutions":["Delete any partially downloaded VSIX and retry the download (transient network corruption is the most common cause).","Verify the actual checksum: sha256sum of the downloaded VSIX and compare with the expected hash baked into the code/config.","If Open VSX published a new vshaxe release, update the expected_sha (or pinned version + hash) in the code.","Check for corporate proxy/MITM interference and retry from an unrestricted network."],"exampleFix":"# before (stale pinned hash for an old VSIX)\nexpected_sha = \"9f2c...old\"\n# after (hash of the current release)\n# sha256sum vshaxe-*.vsix\nexpected_sha = \"4ab1...new\"","handlingStrategy":"validation","validationCode":"import hashlib, pathlib\ndef validate_vsix(path: str, expected_sha: str) -> bool:\n    p = pathlib.Path(path)\n    if not p.is_file() or p.stat().st_size == 0:\n        return False\n    h = hashlib.sha256()\n    with p.open(\"rb\") as f:\n        for chunk in iter(lambda: f.read(8192), b\"\"):\n            h.update(chunk)\n    return h.hexdigest().lower() == expected_sha.lower()","typeGuard":null,"tryCatchPattern":"try:\n    path = get_or_install_haxe_ls()\nexcept RuntimeError as e:\n    if \"checksum mismatch\" in str(e):\n        retry_download_with_backoff()  # file already deleted by library\n    else:\n        raise","preventionTips":["Re-download before assuming tampering — most mismatches are truncated downloads.","Keep the pinned VSIX version and expected_sha in sync; update both together on release bumps.","Verify checksums manually (sha256sum) when behind proxies or TLS-intercepting firewalls.","Download to a temp file and validate before replacing any cached artifact."],"tags":["python","checksum","sha256","download-integrity","network"],"backgroundTag":"sha256-checksum-mismatch","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}