oraios/serena · error
ShellCheck binary not found at {binary_path} after extractio
Error message
ShellCheck binary not found at {binary_path} after extraction; archive layout may have changed. What it means
Raised by _install_shellcheck_if_missing after downloading and extracting the ShellCheck release archive: the expected shellcheck binary was not found at its expected path. The library throws this because it downloads a pinned release and assumes a known archive layout; if the binary is missing after extraction, the upstream archive structure likely changed or the extraction silently failed.
Source
Thrown at src/solidlsp/language_servers/bash_language_server.py:181
install_dir = _shellcheck_install_dir(bash_ls_dir)
os.makedirs(install_dir, exist_ok=True)
release = _SHELLCHECK_DEPENDENCIES.get(PlatformUtils.get_platform_id())
if release is None:
raise RuntimeError(f"ShellCheck has no upstream binary release for platform {PlatformUtils.get_platform_id().value}")
archive_type = "zip" if os.name == "nt" else "xztar"
log.info(f"Downloading ShellCheck v{_SHELLCHECK_VERSION} for {PlatformUtils.get_platform_id().value}")
FileUtils.download_and_extract_archive_verified(
release["url"],
install_dir,
archive_type,
expected_sha256=release["sha256"],
allowed_hosts=_SHELLCHECK_ALLOWED_HOSTS,
)
if not os.path.exists(binary_path):
raise FileNotFoundError(f"ShellCheck binary not found at {binary_path} after extraction; archive layout may have changed.")
# ensure the binary is executable on POSIX (zip extraction does not preserve perms)
if os.name != "nt":
current = os.stat(binary_path).st_mode
os.chmod(binary_path, current | 0o111)
def create_launch_command_env(self) -> dict[str, str]:
bash_language_server_version = self._custom_settings.get("bash_language_server_version", DEFAULT_BASH_LANGUAGE_SERVER_VERSION)
bash_ls_dir = self._resolve_bash_ls_dir(bash_language_server_version)
managed_bin_dir = os.path.join(bash_ls_dir, "node_modules", ".bin")
return {
"PATH": managed_bin_dir + os.pathsep + os.environ.get("PATH", ""),
"SHELLCHECK_PATH": _shellcheck_binary_path(bash_ls_dir),
}
def _resolve_bash_ls_dir(self, bash_language_server_version: str) -> str:
# legacy unversioned dir reserved for INITIAL; every other version goes into a versioned subdir
ls_dirname = (View on GitHub (pinned to 7fcbca7e62)
Solutions
- Check the extracted directory (ls the install dir under bash-lsp*/shellcheck) to see the actual archive layout and where the binary landed
- Clear the managed install directory so a fresh download/extraction is attempted
- Pin/report the ShellCheck version: install shellcheck system-wide via package manager so the managed install is skipped (os.path.exists early-returns)
- Update the library to a version matching the current upstream ShellCheck archive layout
Example fix
# before (managed install fails) BashLanguageServer(...) # raises FileNotFoundError after extraction // after # pre-install shellcheck system-wide so the managed install path is skipped sudo apt-get install shellcheck BashLanguageServer(...) # works
Defensive patterns
Strategy: validation
Validate before calling
import os, shutil
if shutil.which("shellcheck") is None and not os.path.exists(os.path.join(ls_resources_dir, "bash-lsp", "shellcheck", "shellcheck")):
print("shellcheck will be managed-installed; if it fails, pre-install shellcheck system-wide") Try / catch
try:
BashLanguageServer(...)
except FileNotFoundError as e:
if "ShellCheck binary not found" in str(e):
# fall back to system shellcheck or clear the install dir and retry
shutil.which("shellcheck") or install_shellcheck_via_pkg_manager()
else:
raise Prevention
- Pre-install shellcheck via your system package manager so the managed download path is never used
- Clear the managed bash-lsp install directory after upgrading the library or shellcheck version
- Check the extracted archive layout if you pin a custom bash_language_server_version
When it happens
Trigger: Calling BashLanguageServer startup (_get_or_install_core_dependency -> _install_shellcheck_if_missing) when shellcheck is not already present, the pinned release URL/SHA is downloaded and extracted successfully, but _shellcheck_binary_path(bash_ls_dir) does not exist afterwards (e.g. archive now nests the binary in a different subdirectory, partial extraction, or disk issue).
Common situations: Upstream ShellCheck GitHub release changes its archive layout (renames/renests the binary); corrupted or truncated download that extracts but omits the binary; a proxy/mirror serving a different archive; filesystem errors during extraction; a stale pinned version in the library.
Related errors
- Clangd executable not found at {clangd_executable_path}. Mak
- Memory maintenance template not found at {template_path}
- dotnet executable not found at {dotnet_exe} after installati
- Failed to install .NET {version} runtime using install scrip
- Failed to install .NET {version} runtime: {e}
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/bbce8e37e969af2c.
Report an issue: GitHub.