tonhowtf/omniget · error

trecho {}: o fim tem de vir depois do começo

Error message

trecho {}: o fim tem de vir depois do começo

What it means

validate_segments rejects a SponsorBlock segment whose end time is not strictly after its start time. For non-point actions (not "poi"/"full"), a segment represents a time range, so an end <= start would describe an empty or inverted range and is meaningless to the SponsorBlock API. The check runs after the finite/non-negative check, so this is specifically about ordering, not validity of the numbers themselves.

Solutions

  1. Fix the segment data so end > start for range-type segments before calling build_payload.
  2. Use action_type "poi" or "full" if the segment is a single point in time (only start matters).
  3. Add client-side validation on input fields: end must be greater than start.
  4. Check for swapped start/end values if the segment came from an import or conversion step.

Example fix

// before
NewSegment { action_type: "skip".into(), start: 42.0, end: 42.0, .. }
// after
NewSegment { action_type: "skip".into(), start: 42.0, end: 57.5, .. }
Defensive patterns

Strategy: validation

Validate before calling

fn valid_range(s: &NewSegment) -> bool {
    let pontual = s.action_type == "poi" || s.action_type == "full";
    pontual || s.end > s.start
}

Type guard

fn is_valid_segment(s: &NewSegment) -> bool {
    s.start.is_finite() && s.end.is_finite() && s.start >= 0.0 && (s.end > s.start || matches!(s.action_type.as_str(), "poi" | "full"))
}

Try / catch

match build_payload(&id, &user, dur, &segs) {
    Err(e) if e.to_string().contains("o fim tem de vir depois do começo") => warn_user_about_segment_times(),
    other => other?,
}

Prevention

When it happens

Trigger: Calling build_payload (via submit) with a NewSegment whose action_type is "skip", "mute", or "chapter" and whose end <= start, e.g. start=10.0, end=10.0 or end=5.0.

Common situations: A UI letting users type end times freely; swapped start/end fields when converting from another segment format; zero-length segments used as 'markers' instead of a poi action; off-by-one when computing end from start+length with length=0.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

            return Err(anyhow!(
                "trecho {}: categoria desconhecida ({})",
                n,
                s.category
            ));
        }
        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));
        }

View on GitHub (pinned to 8600b91f42)