{"record":{"id":"b924617e7ba21853","repo":"tonhowtf/omniget","slug":"trecho-tempo-inv-lido","errorCode":null,"errorMessage":"trecho {}: tempo inválido","messagePattern":"trecho (.+?): tempo inválido","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/sponsorblock.rs","lineNumber":233,"sourceCode":"    }\n    for (i, s) in segments.iter().enumerate() {\n        let n = i + 1;\n        if !CATEGORIES.contains(&s.category.as_str()) {\n            return Err(anyhow!(\n                \"trecho {}: categoria desconhecida ({})\",\n                n,\n                s.category\n            ));\n        }\n        if !ACTION_TYPES.contains(&s.action_type.as_str()) {\n            return Err(anyhow!(\n                \"trecho {}: tipo de ação desconhecido ({})\",\n                n,\n                s.action_type\n            ));\n        }\n        if !s.start.is_finite() || !s.end.is_finite() || s.start < 0.0 || s.end < 0.0 {\n            return Err(anyhow!(\"trecho {}: tempo inválido\", n));\n        }\n        let pontual = s.action_type == \"poi\" || s.action_type == \"full\";\n        if !pontual && s.end <= s.start {\n            return Err(anyhow!(\"trecho {}: o fim tem de vir depois do começo\", n));\n        }\n        if s.action_type == \"chapter\" && s.description.trim().is_empty() {\n            return Err(anyhow!(\"trecho {}: capítulo precisa de um título\", n));\n        }\n        if duration > 0.0 && s.end > duration + 1.0 {\n            return Err(anyhow!(\"trecho {}: passa do fim do vídeo\", n));\n        }\n    }\n    // Sobreposição só importa entre trechos que pulam pedaço.\n    let mut cortes: Vec<&NewSegment> = segments\n        .iter()\n        .filter(|s| s.action_type == \"skip\" || s.action_type == \"mute\")\n        .collect();\n    cortes.sort_by(|a, b| a.start.total_cmp(&b.start));","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/sponsorblock.rs#L215-L251","documentation":"Numeric sanity check in `validate_segments`: start and end must both be finite (not NaN/inf) and non-negative. Invalid numbers are rejected locally with the 1-based segment index before a rate-limited submission is spent.","triggerScenarios":"Calling `validate_segments`/`build_payload` with a segment where `start` or `end` is NaN, infinite, negative, or otherwise non-finite — typically from uninitialized UI fields, division results, or JSON parsed from bad data.","commonSituations":"Timestamp fields left empty becoming NaN in the UI; a buggy parser emitting -1 as a sentinel; deserializing segments from corrupted/edited JSON; float overflow computing timestamps.","solutions":["Ensure start/end are finite non-negative numbers before constructing NewSegment.","Treat empty timestamp inputs as an error in the UI rather than letting NaN through.","Use checked parsing (e.g. str::parse::<f64>() with error handling) instead of defaulting to NaN.","Clamp or reject negative values at the segment-creation site."],"exampleFix":"// before\nlet seg = NewSegment { start: f64::NAN, end: 30.0, .. };\n// after\nlet start: f64 = \"10\".parse()?;\nlet seg = NewSegment { start, end: 30.0, .. };","handlingStrategy":"validation","validationCode":"fn valid_times(seg: &NewSegment) -> bool {\n    seg.start.is_finite() && seg.end.is_finite() && seg.start >= 0.0 && seg.end >= 0.0\n}","typeGuard":"fn finite_nonnegative(x: f64) -> bool {\n    x.is_finite() && x >= 0.0\n}","tryCatchPattern":null,"preventionTips":["Parse timestamps with checked f64 parsing; never default to NaN.","Reject empty timestamp UI fields at input time.","Clamp negatives to 0 or reject at segment creation.","Guard division math that produces timestamps against division by zero."],"tags":["validation","numeric","sponsorblock"],"backgroundTag":"invalid-argument-value","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}