GitoxideLabs/gitoxide · error

Failed to subtract from

Error message

Failed to subtract {duration} from {now}

What it means

gix-date's relative-date parser (`subtract_duration`, used by `parse_named`) computes an absolute timestamp by subtracting a parsed duration (e.g. from "2 hours ago") from the current time via `checked_sub`. This error is raised when that arithmetic overflows — the duration is too large to subtract from the given `now` timestamp — and wraps the failure with context showing the duration and the base time.

Solutions

  1. Validate the magnitude of the relative duration before parsing (reject absurdly large numbers).
  2. Provide a sane `now` reference (`Some(&Zoned::now())`) so subtraction happens in a normal range.
  3. Catch the error and surface 'invalid relative date' to the user instead of propagating.

Example fix

// before: extreme spec overflows when subtracted from now
let t = gix_date::parse::named("99999999999 years ago", Some(&now))?;

// after: bound the numeric part before parsing
let n: u64 = spec.trim_end_matches(...).parse()?;
if n > 1_000_000 { return Err(anyhow::anyhow!("relative date too large")); }
let t = gix_date::parse::named(spec, Some(&now))?;
Defensive patterns

Strategy: try-catch

Validate before calling

let n: u64 = /* numeric part of spec */;
if n > 1_000_000 { return Err(anyhow::anyhow!("relative date magnitude too large")); }

Try / catch

match gix_date::parse::named(spec, Some(&now)) {
    Ok(t) => t,
    Err(_) => anyhow::bail!("invalid relative date: {spec}"),
}

Prevention

When it happens

Trigger: Calling `gix_date::parse::named` (or the relative parser it delegates to) with a relative date spec whose duration exceeds the representable timestamp range when subtracted from `now`, e.g. an enormous number of years/durations near the timestamp limits.

Common situations: User-supplied free-form date input like "999999999999 years ago" accepted by a CLI or config; fuzzed or malicious input to a date parser; unit tests passing extreme durations.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/9ffd4cfedcedac62. Report an issue: GitHub.

Appendix: source

Thrown at gix-date/src/parse/relative.rs:213

                let months = count.checked_mul(*factor).ok_or_else(err)?;
                fields = fields.normalize()?.into();
                let total = (i64::from(fields.year) * 12 + i64::from(fields.month) - 1)
                    .checked_sub(months)
                    .ok_or_else(err)?;
                fields.year = i16::try_from(total.div_euclid(12)).ok().ok_or_else(err)?;
                fields.month = i8::try_from(total.rem_euclid(12) + 1).expect("a value in 1..=12");
            }
        }
    }
    fields.normalize()
}

fn subtract_duration(now: Option<&Zoned>, duration: SignedDuration) -> Result<Zoned, Exn<ValidationError>> {
    let now = now.ok_or(ValidationError::new("Missing current time"))?;
    now.timestamp()
        .checked_sub(duration)
        .map(|timestamp| timestamp.to_zoned(now.time_zone().clone()))
        .or_raise(|| Error::new(format!("Failed to subtract {duration} from {now}")))
}

View on GitHub (pinned to e73179060b)