* fix(errors): a failed download is not a broken install (#1347, #1335)
Two reports, one shape: the error text carried both a network cause and a
downstream symptom, the taxonomy matched the symptom first, and the user
was sent to fix something that was never broken.
#1347 -- transcription failed with "transformers ASR pipeline failed to
import (AutoFeatureExtractor) -- your transformers install is incomplete;
reinstall with `uv pip install --reinstall transformers` ... Underlying:
Cannot send a request, as the client has been closed."
The install is fine. The pipeline was DOWNLOADING the feature extractor
when the shared HTTP client closed underneath it (#880). Reinstalling
transformers cannot fix a dropped connection, so the advice was not
merely unhelpful -- it was work the user could repeat forever without
succeeding. New MODEL_DOWNLOAD_INTERRUPTED class, checked before the
import rules, requiring the httpx closed-client wording AND an
import/transformers term so a bare closed-client error elsewhere is left
alone. Its hint says the partial download resumes, since otherwise
someone on a slow link assumes retrying restarts a multi-GB fetch.
#1335 -- a cut TLS connection reached /generate as a bare 500 carrying
`_ssl.c:1016`. core/failure.py has classified that since #1301, but
/generate keeps its own taxonomy and never learned it, so it fell to the
unrecognized-error catch-all. Added to the network signatures there: it
is a dropped download, and the remedy is retry, not Flush.
Both changes are orderings rather than new detections -- the cause now
beats the symptom -- and both keep the case the original rule existed
for: a genuinely broken transformers install still classifies as
TRANSFORMERS_IMPORT, and a failed handshake is still distinguished from a
cut connection.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(errors): a Windows paging-file limit is not out-of-memory (#1334)
Same class as the two fixes already on this branch: advice that cannot
work.
The reporter asked, reasonably, whether OmniVoice needs an internet
connection -- generation failed only when they disconnected, with a bare
500 carrying "The paging file is too small for this operation to complete
(os error 1455)". Two separate defects made that unanswerable:
1. /generate matched it in _is_oom_failure and said "Try the Flush button
to reload the model". Flush cannot help. The hint we had already
written for this exact class says so outright -- "closing other apps
usually won't fix it" -- but the generate path never consulted it.
Now branched before the OOM check, naming the virtual-memory setting
and stating plainly that it is not a network problem.
2. WINDOWS_PAGING_FILE_TOO_SMALL was absent from
_CONTEXT_FREE_HINT_CLASSES, so on the raw-500 surface classify()
identified it correctly and then attached nothing. The user got the OS
sentence and no next step, despite the detailed remedy sitting in
_HINTS. Its trigger (1455 with winerror/os error, or the literal
phrase) is unmistakable, which is the bar that set requires.
Both Python (`WinError 1455`) and Rust (`os error 1455`, from the
safetensors mmap) spellings are covered, and a genuine CUDA OOM still
gets the Flush hint.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(errors): tighten both new matches, and move the 1455 expectation
CI caught a real one, and it was my process error: I ran the full sweep
before adding the paging-file change, not after.
tests/test_generation_audio_guard.py listed WinError 1455 among the OOM
signatures and asserted it yields "ran out of memory / try Flush". The
new branch routes it to the paging-file advice instead. That test's
INTENT -- a genuine memory failure must never fall through to the unknown
catch-all -- is preserved and still asserted; 1455 simply gets a more
specific memory message now. Expectation moved, guard kept.
Two over-broad matches tightened (CodeRabbit), both in the same
direction: a rule that fires too widely replaces correct advice with
advice that cannot work, which is the exact defect this branch exists to
fix.
* The TLS EOF wording is OpenSSL's, but nothing stops an unrelated
component saying something similar, and calling a local fault a network
problem sends the user to check a connection that was never involved.
Now gated on an `ssl` marker; the real message always carries it.
* MODEL_DOWNLOAD_INTERRUPTED required "client has been closed" OR
"cannot send a request". The latter alone is generic enough to appear
beside an unrelated import failure, where overriding TRANSFORMERS_IMPORT
would swap correct reinstall advice for a "just retry" that never
succeeds. Now requires the closed-client wording itself.
Negative regression tests for both, plus the positive cases they must not
cost us. Also resolves core.failure through a fixture at call time rather
than importing it at module level, per the suite convention -- sibling
tests reload these modules and a stale binding makes the file
order-dependent.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: debpalash <nizam4103@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>