Zackriya-Solutions/meetily · error

Time went backwards

Error message

Time went backwards

What it means

SystemTime::now().duration_since(UNIX_EPOCH) returns Err exactly when the current wall clock reads a time before 1970-01-01. The .expect("Time went backwards") panics the audio-processing thread on such a clock; this is the std::time API's only failure mode.

Source

Thrown at frontend/src-tauri/src/audio/stt.rs:221

            crossbeam::select! {
                recv(input_receiver) -> input_result => {
                    match input_result {
                        Ok(mut audio) => {
                            // Check if device should be recording
                            if let Some(control) = audio_devices_control.as_ref().unwrap().get(&audio.device) {
                                if !control.is_running {
                                    debug!("Skipping audio processing for stopped device: {}", audio.device);
                                    continue;
                                }
                            } else {
                                debug!("Device not found in control list: {}", audio.device);
                                continue;
                            }

                            debug!("Received input from input_receiver");
                            let timestamp = SystemTime::now()
                                .duration_since(UNIX_EPOCH)
                                .expect("Time went backwards")
                                .as_secs();

                            let audio_data = if audio.sample_rate != m::SAMPLE_RATE as u32 {
                                match resample(
                                    audio.data.as_ref(),
                                    audio.sample_rate,
                                    m::SAMPLE_RATE as u32,
                                ) {
                                    Ok(data) => data,
                                    Err(e) => {
                                        error!("Error resampling audio: {:?}", e);
                                        continue;
                                    }
                                }
                            } else {
                                audio.data.as_ref().to_vec()
                            };

View on GitHub (pinned to 0281737d87)

Solutions

  1. Replace expect with .unwrap_or_default(): a 0-second timestamp is tolerable for chunk sequencing
  2. Use a monotonic Instant for in-session ordering and system time only for display labels
  3. If wall-clock seconds are required across resets, compute signed epoch millis instead of unsigned duration_since

Example fix

// before
let timestamp = SystemTime::now()
    .duration_since(UNIX_EPOCH)
    .expect("Time went backwards")
    .as_secs();

// after
let timestamp = SystemTime::now()
    .duration_since(UNIX_EPOCH)
    .map(|d| d.as_secs())
    .unwrap_or(0);
Defensive patterns

Strategy: fallback

Try / catch

let timestamp = SystemTime::now()
    .duration_since(UNIX_EPOCH)
    .map(|d| d.as_secs())
    .unwrap_or(0); // tolerate pre-epoch clocks

Prevention

When it happens

Trigger: The STT receive loop is running while the OS clock sits before the Unix epoch: dead RTC/CMOS battery resetting a laptop to 1969/1970, a VM restored from a snapshot with a stale clock, manual clock setting, or a broken NTP step.

Common situations: Machines with failed clock batteries booting to epoch-zero, virtualization snapshots, offline kiosks without time sync, dual-boot clock disputes.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16). Data as JSON: /api/errors/2edfd26020ce1b21. Report an issue: GitHub.