tonhowtf/omniget · error
subtitle_translate error surfaced to user via err()…
Error message
subtitle_translate error surfaced to user via err() (localized toast)
What it means
translateAll failed while invoking subtitle_translate to machine-translate all cues to the target language; err() surfaces the backend error as a localized toast and cues are left unchanged. A raw 'ai_not_configured' code from the backend is specifically mapped to a 'not configured' message.
Solutions
- If the toast shows the not-configured message, configure the AI/translation provider and key in backend settings.
- Validate targetLang is a non-empty supported language code before invoking.
- Check upstream API status/limits if the error mentions request failure or rate limiting.
- Retry smaller batches of cues if payload size is the issue.
Example fix
// before
await invoke("subtitle_translate", { cues, targetLang: targetLang.trim() });
// after
const lang = targetLang.trim();
if (!lang) { showToast("error", $t("downloads.sw.enter_language")); return; }
await invoke("subtitle_translate", { cues, targetLang: lang }); Defensive patterns
Strategy: validation
Validate before calling
const lang = targetLang.trim();
if (!lang) { showToast("error", $t("downloads.sw.enter_language")); return; }
if (!(await invoke<boolean>("ai_configured").catch(() => false))) { err("ai_not_configured"); return; } Type guard
function isValidTargetLang(v: unknown): v is string {
return typeof v === "string" && /^[a-z]{2}(-[A-Z]{2})?$/.test(v.trim());
} Try / catch
try {
cues = await invoke<Cue[]>("subtitle_translate", { cues, targetLang: lang });
showToast("success", $t("downloads.sw.translated") as string);
} catch (e) {
err(e); // localized toast; maps ai_not_configured etc.
} finally {
busy = false;
} Prevention
- Configure the AI/translation provider and key before exposing translate in the UI.
- Validate the target language code client-side before invoking.
- Check AI provider quota/limits and back off on rate-limit errors.
- Chunk very large cue lists to avoid oversized requests.
When it happens
Trigger: invoke('subtitle_translate',{cues,targetLang}) rejecting — AI/translation backend not configured (ai_not_configured), empty/invalid targetLang, API failure upstream (rate limit, key invalid), or cues payload rejected.
Common situations: No AI provider/API key configured on the backend; empty or malformed target language string; translation service outage or quota exhaustion; extremely large subtitle files exceeding request limits.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- subtitle_grammar_fix error surfaced to user via err()…
- $t('common.error') | mapped: ai_not_configured ->…
- subtitle_load error surfaced to user via err() (localized…
- waveform_peaks/detect_shot_changes error surfaced to user…
- escolha a pasta de destino para organizar
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/684b824ce08cdb93.
Report an issue: GitHub.
Appendix: source
Thrown at src/components/downloads/SubtitleWorkshop.svelte:163
if (i < cues.length - 1 && cues[i + 1].start_ms < c.end_ms)
return $t("downloads.sw.qc_overlap") as string;
const secs = (c.end_ms - c.start_ms) / 1000;
const cps = secs > 0 ? c.text.replace(/\s/g, "").length / secs : 99;
if (cps > 21) return $t("downloads.sw.qc_fast") as string;
return null;
}
async function translateAll() {
if (!targetLang.trim() || !cues.length || busy) return;
busy = true;
try {
cues = await invoke<Cue[]>("subtitle_translate", {
cues,
targetLang: targetLang.trim(),
});
showToast("success", $t("downloads.sw.translated") as string);
} catch (e) {
err(e);
} finally {
busy = false;
}
}
async function grammarFix() {
if (!cues.length || busy) return;
busy = true;
try {
cues = await invoke<Cue[]>("subtitle_grammar_fix", {
cues,
style: grammarStyle,
});
showToast("success", $t("downloads.sw.grammar_done") as string);
} catch (e) {
err(e);
} finally {
busy = false;View on GitHub (pinned to 8600b91f42)