tonhowtf/omniget · error

dois trechos se sobrepõem em

Error message

dois trechos se sobrepõem em {:.1}s

What it means

validate_segments collects all skip/mute segments, sorts them by start, and rejects any adjacent pair where the next segment starts before the previous one ends — i.e. two cut segments overlap, and the overlap would be skipped twice. The error reports the start time of the second segment and the overlap size in seconds.

Solutions

  1. Adjust the segment boundaries so skip/mute ranges do not overlap (e.g. end the first at 25.0 or start the second at 30.0).
  2. Merge overlapping segments into one before calling build_payload.
  3. Keep at most one skip/mute segment covering any given time range.
  4. Note only skip/mute are checked — overlapping chapters/poi entries are fine; reclassify one segment if overlap is intended.

Example fix

// before
segments: [ {"skip", 10.0, 30.0}, {"mute", 25.0, 40.0} ]
// after
segments: [ {"skip", 10.0, 25.0}, {"mute", 25.0, 40.0} ]
Defensive patterns

Strategy: validation

Validate before calling

fn no_overlapping_cuts(segments: &[NewSegment]) -> bool {
    let mut c: Vec<_> = segments.iter().filter(|s| matches!(s.action_type.as_str(), "skip" | "mute")).collect();
    c.sort_by(|a, b| a.start.total_cmp(&b.start));
    c.windows(2).all(|w| w[1].start >= w[0].end)
}

Type guard

fn overlaps(a: &NewSegment, b: &NewSegment) -> bool {
    matches!(a.action_type.as_str(), "skip" | "mute") && matches!(b.action_type.as_str(), "skip" | "mute") && b.start < a.end
}

Try / catch

match build_payload(&id, &user, dur, &segs) {
    Err(e) if e.to_string().contains("se sobrepõem") => open_overlap_editor()?,
    other => other?,
}

Prevention

When it happens

Trigger: Calling build_payload/submit with two or more segments of type "skip" or "mute" whose time ranges intersect, e.g. [10.0–30.0] and [25.0–40.0].

Common situations: Users adding overlapping 'skip sponsor' and 'skip self-promo' sections over the same part of a video; importing segments from another tool that allowed overlaps; merging segment lists by concatenation instead of by time.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

        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(
    video_id: &str,
    user_id: &str,
    duration: f64,
    segments: &[NewSegment],
) -> anyhow::Result<serde_json::Value> {
    if video_id.len() != 11 {
        return Err(anyhow!("não reconheci o vídeo do YouTube"));
    }
    if user_id.trim().len() < 30 {
        return Err(anyhow!("a chave local do SponsorBlock está corrompida"));
    }

View on GitHub (pinned to 8600b91f42)