disable Bun's fetch timeout when calling whisper

Bun's fetch aborts at 300s by default. whisper.cpp runs at roughly 8x realtime,
so a 43-minute recording needs about 5.4 minutes and died with "The operation
timed out" some 20 seconds short of the answer — long enough to look like a slow
machine rather than a ceiling.

AbortSignal.timeout() does not raise that ceiling; only `timeout: false` does,
which the DOM RequestInit type does not declare, hence the local BunRequestInit.

Verified end to end: a 43-minute episode through the task now completes in 547s
with a 27k-character transcript, where it previously failed at exactly 300s.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
brunorezio
2026-07-26 05:07:38 +01:00
co-authored by Claude Opus 5
parent 4331882693
commit 96dd1bfe9e
+20 -2
View File
@@ -6,6 +6,16 @@
//
// The detection must win when Whisper is confident. `spokenLanguages` only breaks ties on clips
// Whisper is genuinely unsure about, where its low-confidence guess defaults to English.
//
// Both requests pass `timeout: false`. Bun's fetch aborts at 300s by default, and whisper.cpp runs at
// roughly 8x realtime, so anything over ~40 minutes of audio died with "The operation timed out"
// about 20 seconds short of the answer. AbortSignal.timeout() does not raise that ceiling — only
// disabling the built-in timeout does.
// Bun's fetch accepts `timeout: false` to disable its built-in 300s ceiling. The DOM RequestInit
// type this project compiles against does not declare it, so widen it here rather than casting at
// each call site.
type BunRequestInit = RequestInit & { timeout?: boolean | number };
type TranscribeArgs = {
file: File | Blob;
@@ -52,7 +62,11 @@ export async function transcribeAudio({
detectForm.append('response_format', 'verbose_json');
detectForm.append('detect_language', 'true');
const detectRes = await fetch(`${base}/inference`, { method: 'POST', body: detectForm });
const detectRes = await fetch(`${base}/inference`, {
method: 'POST',
body: detectForm,
timeout: false,
} as BunRequestInit);
if (!detectRes.ok) throw new Error(`Language detection failed (${detectRes.status})`);
const detectJson = (await detectRes.json()) as {
language?: string;
@@ -93,7 +107,11 @@ export async function transcribeAudio({
transcribeForm.append('response_format', 'text');
transcribeForm.append('language', detectedLanguage);
const res = await fetch(`${base}/inference`, { method: 'POST', body: transcribeForm });
const res = await fetch(`${base}/inference`, {
method: 'POST',
body: transcribeForm,
timeout: false,
} as BunRequestInit);
if (!res.ok) throw new Error(`Transcription failed (${res.status})`);
const text = (await res.text()).trim();