fix(install): verify the unsloth CLI exists before declaring WSL success

The WoA WSL path gated success solely on torch.cuda.is_available(), but
install.sh can exit after PyTorch yet before the `unsloth` package/console
script (e.g. a transient `uv pip install unsloth`). torch would still import,
so the installer wrote a Windows shim pointing at
/root/.unsloth/studio/unsloth_studio/bin/unsloth and reported success even
though that binary was absent -- `unsloth studio` then fails "no such file".
$wslRc can't distinguish this (it also goes non-zero on the optional llama
prebuilt step). Now `test -x` the exact shim target; if missing, fall through
to the existing failure path (restore rollback + non-zero exit) instead of
creating a dangling shim. Verified on N1X: present->exit 0 (success kept),
absent->exit 1 (fails). Addresses Codex review 4494521902.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel Han 2026-06-14 21:56:45 -07:00
commit aa2c4ba3eb

View file

@ -1967,6 +1967,20 @@ shell.Run cmd, 0, False
& wsl.exe -d $distro --cd /root -u root -- /root/.unsloth/studio/unsloth_studio/bin/python -c "import torch,sys; sys.exit(0 if torch.cuda.is_available() else 3)" *> $null
$torchOk = ($LASTEXITCODE -eq 0)
} catch {} finally { $ErrorActionPreference = $prevEapChk }
# torch.cuda alone isn't success: install.sh can exit after PyTorch but before the `unsloth`
# package/console script (e.g. a transient `uv pip install unsloth`), and $wslRc can't tell
# (it also goes non-zero on the optional llama prebuilt step). Verify the exact binary the shim
# execs exists -- else we'd write a dangling shim and report a broken install as success.
if ($torchOk) {
$prevEapCli = $ErrorActionPreference; $ErrorActionPreference = "Continue"
$global:LASTEXITCODE = -1
try { & wsl.exe -d $distro --cd /root -u root -- test -x /root/.unsloth/studio/unsloth_studio/bin/unsloth *> $null } catch {}
$ErrorActionPreference = $prevEapCli
if ($LASTEXITCODE -ne 0) {
substep "WSL install incomplete: 'unsloth' CLI missing (install.sh cut short after PyTorch) -- not creating a dangling shim." "Yellow"
$torchOk = $false
}
}
# Self-heal web-server deps: a cut-short install.sh "studio deps" step leaves torch + unsloth but
# no fastapi/uvicorn/structlog/starlette (`unsloth studio` dies). Reinstall them unpinned (no
# huggingface-hub/transformers/datasets) so the verified GPU torch stack stays intact.