{"record":{"id":"2cbdf3fd5d2a29cc","repo":"tonhowtf/omniget","slug":"informe-um-link-uma-legenda-ou-um-arquivo-de-m-dia","errorCode":null,"errorMessage":"informe um link, uma legenda ou um arquivo de mídia","messagePattern":"informe um link, uma legenda ou um arquivo de mídia","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/yt_notes.rs","lineNumber":515,"sourceCode":"                ))\n            }\n            Err(e) => return Err(e),\n        }\n    } else if !opts.media_path.trim().is_empty() {\n        let path = std::path::PathBuf::from(opts.media_path.trim());\n        let r = transcribe(&path, &opts, progress.clone()).await?;\n        if meta.title.is_empty() {\n            meta.title = path\n                .file_stem()\n                .map(|s| s.to_string_lossy().to_string())\n                .unwrap_or_default();\n        }\n        meta.language = r.language.clone();\n        meta.duration_seconds = r.seconds;\n        cues = r.cues;\n        source = \"whisper\".to_string();\n    } else {\n        return Err(anyhow!(\n            \"informe um link, uma legenda ou um arquivo de mídia\"\n        ));\n    }\n\n    if cues.is_empty() {\n        return Err(anyhow!(\"a transcrição saiu vazia\"));\n    }\n    super::report(&progress, ID, \"progress\", 4, Some(4), None);\n    let chapters = if opts.use_chapters {\n        meta.chapters.clone()\n    } else {\n        Vec::new()\n    };\n    let boundaries: Vec<i64> = chapters.iter().map(|c| c.start_ms).collect();\n    let paragraphs = stitch_at(&cues, &boundaries, &opts.stitch);\n    let doc = NotesDoc {\n        title: meta.title.clone(),\n        channel: meta.channel.clone(),","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/yt_notes.rs#L497-L533","documentation":"In yt_notes.rs `run`, the tool requires at least one input source: a URL, an existing subtitle/caption input, or a media file for Whisper transcription. If none of these was supplied (or the branches that would populate `cues`/`source` were not taken), it fails fast with this Portuguese message instead of proceeding with empty input. It is a guard against running the transcription pipeline with nothing to process.","triggerScenarios":"Calling `run` with an Options struct where `opts.url` is empty/whitespace, no subtitle file was given, and no media path was provided (the final `else` branch of the source-selection if/else chain).","commonSituations":"A GUI/frontend invokes the yt-notes tool with only a title or topic but no link; a test or script builds options forgetting to set the url field; a user clears the link field but leaves the media/subtitle inputs empty.","solutions":["Set `opts.url` to a valid YouTube (or other supported) video link before calling run.","Provide a subtitle/caption file input when no link is available.","Provide a local media file so the Whisper branch can transcribe it.","In the caller/UI, validate that at least one of link/caption/media is present before invoking the tool."],"exampleFix":"// before\nlet opts = YtNotesOptions::default(); // no url, no media, no captions\nrun(opts).await?;\n// after\nlet opts = YtNotesOptions { url: \"https://www.youtube.com/watch?v=abc\".into(), ..Default::default() };\nrun(opts).await?;","handlingStrategy":"validation","validationCode":"if opts.url.trim().is_empty() && opts.media_path.is_none() && opts.subtitle_path.is_none() {\n    return Err(\"provide a link, a caption or a media file before running yt-notes\");\n}\nrun(opts).await?;","typeGuard":"fn has_source(opts: &YtNotesOptions) -> bool {\n    !opts.url.trim().is_empty() || opts.media_path.is_some() || opts.subtitle_path.is_some()\n}","tryCatchPattern":null,"preventionTips":["Always build options via a constructor that requires at least one source.","Validate inputs in the UI before dispatching the tool.","Add a unit test asserting run() rejects empty option sets early."],"tags":["input-validation","missing-input","rust","anyhow"],"backgroundTag":"missing-required-argument","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}