{"record":{"id":"e1b6ff42c43c3fa4","repo":"gitbutlerapp/gitbutler","slug":"system-time-is-set-before-the-unix-epoch","errorCode":null,"errorMessage":"system time is set before the Unix epoch","messagePattern":"system time is set before the Unix epoch","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/gitbutler-git/src/context.rs","lineNumber":335,"sourceCode":"        .serialize(serializer)\n}\n\nfn remote_tracking_branch_parts(\n    repo: &gix::Repository,\n    branch: &gix::refs::FullNameRef,\n) -> Result<(String, String)> {\n    let (remote, short_name) = extract_remote_name_and_short_name(branch, &repo.remote_names())\n        .ok_or_else(|| anyhow!(\"failed to determine remote and branch name for `{branch}`\"))?;\n    let short_name = std::str::from_utf8(short_name.as_ref())\n        .context(format!(\"branch name for `{branch}` is not valid UTF-8\"))?\n        .to_owned();\n    Ok((remote, short_name))\n}\n\nfn now_ms() -> u128 {\n    UNIX_EPOCH\n        .elapsed()\n        .expect(\"system time is set before the Unix epoch\")\n        .as_millis()\n}\n\nasync fn handle_git_prompt_push(\n    prompt: String,\n    askpass: Option<Option<StackId>>,\n) -> Option<String> {\n    if let Some(branch_id) = askpass {\n        tracing::info!(\"received prompt for branch push {branch_id:?}: {prompt:?}\");\n        askpass::get_broker()\n            .expect(\"askpass broker must be initialized\")\n            .submit_prompt(prompt, askpass::Context::Push { branch_id })\n            .await\n    } else {\n        tracing::warn!(\"received askpass push prompt but no broker was supplied; returning None\");\n        None\n    }\n}","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/gitbutler-git/src/context.rs#L317-L353","documentation":"now_ms() (gitbutler-git/src/context.rs:332) timestamps push/fetch activity via UNIX_EPOCH.elapsed(). SystemTime::elapsed returns Err when the current wall clock is before 1970-01-01, and the expect turns that into a panic. Everything around it is fallible, so this fires solely on a machine whose clock reads pre-epoch.","triggerScenarios":"A push or fetch through gitbutler-git hitting now_ms() while the OS clock is set before the Unix epoch: dead CMOS battery booting to 1970, a VM restored from a snapshot with a broken RTC, or CI/containers with mocked or unset time.","commonSituations":"Laptops with dead clock batteries, VMs after host suspend/restore without guest-tools time sync, time-mocking test frameworks that install fixed old timestamps, fresh embedded devices without RTC/NTP.","solutions":["Fix the system clock and enable NTP (timedatectl set-ntp true on Linux, w32tm /resync on Windows)","In VMs, sync guest time to the host via hypervisor tools before running GitButler operations","If you own the call site, degrade gracefully with unwrap_or_default() instead of panicking (see exampleFix)"],"exampleFix":"// before\nUNIX_EPOCH.elapsed().expect(\"system time is set before the Unix epoch\").as_millis()\n\n// after\nUNIX_EPOCH.elapsed().map(|d| d.as_millis()).unwrap_or(0)","handlingStrategy":"fallback","validationCode":"// Before running git network ops, sanity-check the clock\nif std::time::SystemTime::now()\n    .duration_since(std::time::UNIX_EPOCH)\n    .is_err()\n{\n    // refuse to start or force a time sync before pushing/fetching\n}","typeGuard":null,"tryCatchPattern":"// Degrade gracefully: a bad clock should yield 0, not a crash\nlet ms = UNIX_EPOCH.elapsed().map(|d| d.as_millis()).unwrap_or(0);","preventionTips":["Enable NTP on machines and VMs that run GitButler operations","Sync guest clocks after VM snapshot restores","Avoid time-mocking frameworks that set pre-epoch timestamps around network code"],"tags":["rust","system-time","clock","unix-epoch","vm","panic"],"backgroundTag":"system-clock-before-epoch","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}