tonhowtf/omniget · error

trecho : passa do fim do vídeo

Error message

trecho {}: passa do fim do vídeo

What it means

validate_segments rejects any segment whose end time exceeds the video duration by more than a 1.0s tolerance. SponsorBlock would otherwise store a segment pointing past the end of the video, which cannot be skipped. The 1s slack absorbs small rounding differences in user-reported durations.

Solutions

  1. Fetch the accurate video duration and pass it as the duration parameter to build_payload.
  2. Clamp segment end to min(end, duration) before submitting.
  3. Re-author the segment against the correct video if the timestamps came from a different cut.
  4. Ensure you are not passing duration = 0.0 (which silently disables this check) when the real duration is known.

Example fix

// before
build_payload(&id, &user, 300.0, &segments) // segment end = 320.0
// after
let dur = fetch_duration(&id).await?; // 330.0
build_payload(&id, &user, dur, &segments)
Defensive patterns

Strategy: validation

Validate before calling

fn within_duration(s: &NewSegment, duration: f64) -> bool {
    duration <= 0.0 || s.end <= duration + 1.0
}

Type guard

fn fits_video(s: &NewSegment, duration: f64) -> bool {
    duration > 0.0 && s.end <= duration + 1.0
}

Try / catch

match build_payload(&id, &user, dur, &segs) {
    Err(e) if e.to_string().contains("passa do fim do vídeo") => clamp_segments(&mut segs, dur),
    other => other?,
}

Prevention

When it happens

Trigger: Calling build_payload/submit with opts.video_duration set to the real length while a segment's end is larger than duration + 1.0 (or duration known and segment measured from a different cut of the video).

Common situations: Duration guessed or rounded down (e.g. trimmed/premium versions); segments authored against a longer preview; stale duration from a previous video reused for the current one; duration 0 passed because it was unknown — note that duration <= 0 skips this check entirely.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/5d559d280e458b85. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/sponsorblock.rs:243

        if !ACTION_TYPES.contains(&s.action_type.as_str()) {
            return Err(anyhow!(
                "trecho {}: tipo de ação desconhecido ({})",
                n,
                s.action_type
            ));
        }
        if !s.start.is_finite() || !s.end.is_finite() || s.start < 0.0 || s.end < 0.0 {
            return Err(anyhow!("trecho {}: tempo inválido", n));
        }
        let pontual = s.action_type == "poi" || s.action_type == "full";
        if !pontual && s.end <= s.start {
            return Err(anyhow!("trecho {}: o fim tem de vir depois do começo", n));
        }
        if s.action_type == "chapter" && s.description.trim().is_empty() {
            return Err(anyhow!("trecho {}: capítulo precisa de um título", n));
        }
        if duration > 0.0 && s.end > duration + 1.0 {
            return Err(anyhow!("trecho {}: passa do fim do vídeo", n));
        }
    }
    // Sobreposição só importa entre trechos que pulam pedaço.
    let mut cortes: Vec<&NewSegment> = segments
        .iter()
        .filter(|s| s.action_type == "skip" || s.action_type == "mute")
        .collect();
    cortes.sort_by(|a, b| a.start.total_cmp(&b.start));
    for par in cortes.windows(2) {
        if par[1].start < par[0].end {
            return Err(anyhow!("dois trechos se sobrepõem em {:.1}s", par[1].start));
        }
    }
    Ok(())
}

/// O corpo exato do `POST /api/skipSegments`.
pub fn build_payload(

View on GitHub (pinned to 8600b91f42)