unslothai/unsloth · info · SttTranscriptionCancelledError

Transcription cancelled.

Error message

Transcription cancelled.

What it means

Raised in the decode loop when the caller-supplied cancel_event is set between frames. Cancellation is polled inside the frame loop precisely so an abandoned upload stops decoding immediately instead of running to EOF or the sample cap.

Source

Thrown at studio/backend/core/inference/stt_sidecar.py:1117

            unit = "minute" if max_minutes == 1 else "minutes"
            raise SttAudioTooLongError(f"Audio must be {max_minutes} {unit} or shorter.")
        raw_buffer.write(array)

    try:
        with av.open(io.BytesIO(audio), mode = "r", metadata_errors = "ignore") as container:
            if not container.streams.audio:
                raise SttAudioDecodeError("Could not decode the audio.")
            frames = iter(container.decode(audio = 0))
            while True:
                try:
                    frame = next(frames)
                except StopIteration:
                    break
                except InvalidDataError:
                    # Skip a corrupt frame rather than fail the whole transcription.
                    continue
                if cancel_event is not None and cancel_event.is_set():
                    raise SttTranscriptionCancelledError("Transcription cancelled.")
                frame.pts = None
                fifo.write(frame)
                if fifo.samples >= 500000:
                    for resampled in resampler.resample(fifo.read()):
                        write_frame(resampled)
            if fifo.samples > 0:
                for resampled in resampler.resample(fifo.read()):
                    write_frame(resampled)
            for resampled in resampler.resample(None):
                write_frame(resampled)
    except (SttAudioDecodeError, SttAudioTooLongError, SttTranscriptionCancelledError):
        raise
    except (FFmpegError, ValueError, RuntimeError) as exc:
        raise SttAudioDecodeError("Could not decode the audio.") from exc
    finally:
        del fifo, resampler

    if sample_count == 0:

View on GitHub (pinned to 203007d190)

Solutions

  1. Treat as a normal control-flow outcome: catch SttTranscriptionCancelledError and discard partial results; nothing is broken.
  2. Ensure the cancel event is only set when you truly want abandonment, and do not reuse a set event across requests.
  3. If cancellation was unexpected, audit who shares the event object — a stale set event cancels every later call.

Example fix

# before
text = stt.transcribe(audio, cancel_event=evt)  # raises if evt set
# after
try:
    text = stt.transcribe(audio, cancel_event=evt)
except SttTranscriptionCancelledError:
    return None  # user abandoned the request
Defensive patterns

Strategy: try-catch

Validate before calling

if cancel_event is not None and cancel_event.is_set():
    return None  # skip the call entirely

Try / catch

try:
    text = stt.transcribe(audio, cancel_event=evt)
except SttTranscriptionCancelledError:
    return {"status": "cancelled", "text": None}

Prevention

When it happens

Trigger: Passing cancel_event to transcribe()/the decode helper and setting it (user hit Stop, another request preempted this one) while PyAV is still yielding frames.

Common situations: A Stop button on a dictation UI; request deduplication where an older duplicate request is cancelled; navigating away from the recording view mid-decode.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/24967d1e75417b8b. Report an issue: GitHub.