jj-vcs/jj · error
SCM-aware Watchman clocks not supported
Error message
SCM-aware Watchman clocks not supported
What it means
In lib/src/fsmonitor.rs, the From impl converting the internal fsmonitor clock into a Watchman clock hits InnerClock::ScmAware and calls unimplemented!(), producing a panic with message 'SCM-aware Watchman clocks not supported'. SCM-aware clocks are a newer Watchman clock flavor (they record source-control state alongside the timestamp) that jj's fsmonitor integration cannot translate into the plain watchman_clock::WatchmanClock representation, so conversion aborts.
Source
Thrown at lib/src/fsmonitor.rs:140
}
};
Self(clock)
}
}
impl From<Clock> for crate::protos::local_working_copy::WatchmanClock {
fn from(clock: Clock) -> Self {
use crate::protos::local_working_copy::watchman_clock;
let Clock(clock) = clock;
let watchman_clock = match clock {
InnerClock::Spec(ClockSpec::StringClock(string_clock)) => {
watchman_clock::WatchmanClock::StringClock(string_clock)
}
InnerClock::Spec(ClockSpec::UnixTimestamp(unix_timestamp)) => {
watchman_clock::WatchmanClock::UnixTimestamp(unix_timestamp)
}
InnerClock::ScmAware(_) => {
unimplemented!("SCM-aware Watchman clocks not supported")
}
};
Self {
watchman_clock: Some(watchman_clock),
}
}
}
#[expect(missing_docs)]
#[derive(Debug, Error)]
pub enum Error {
#[error("Could not connect to Watchman")]
WatchmanConnectError(#[source] watchman_client::Error),
#[error("Could not canonicalize working copy root path")]
CanonicalizeRootError(#[source] std::io::Error),
#[error("Watchman failed to resolve the working copy root path")]View on GitHub (pinned to 6631dbd4a8)
Solutions
- Reset/clear the persisted fsmonitor clock state so a fresh plain clock is created instead of converting the SCM-aware one.
- Use a jj version that supports SCM-aware Watchman clocks (upgrade to match whatever wrote the clock).
- Avoid constructing InnerClock::ScmAware values in your code; map them to UnixTimestamp before conversion, discarding SCM state.
- Disable the fsmonitor (Watchman) integration if SCM-aware clocks keep appearing in your environment.
Example fix
// before
let clock = FsmonitorClock::from(inner); // inner is ScmAware(..) -> panic
// after
let inner = match inner {
InnerClock::ScmAware(_) => InnerClock::Spec(ClockSpec::UnixTimestamp(now)),
other => other,
};
let clock = FsmonitorClock::from(inner); Defensive patterns
Strategy: fallback
Validate before calling
// Normalize the clock before conversion:
let inner = if matches!(inner, InnerClock::ScmAware(_)) {
InnerClock::Spec(ClockSpec::UnixTimestamp(unix_now()))
} else { inner }; Type guard
fn is_supported_clock(inner: &InnerClock) -> bool {
!matches!(inner, InnerClock::ScmAware(_))
} Try / catch
// unimplemented! panics; guard at boundary and fall back to a full scan:
let clock = if is_supported_clock(&inner) {
FsmonitorClock::from(inner)
} else {
FsmonitorClock::fresh() // triggers full re-scan instead of incremental
}; Prevention
- Keep jj versions consistent across machines sharing a working copy.
- Reset persisted fsmonitor clock state after downgrades.
- If using Watchman SCM-aware features, pin a jj version that supports them or disable fsmonitor.
When it happens
Trigger: Constructing the fsmonitor clock type (or its From conversion) from an InnerClock::ScmAware(ClockSpec::ScmAware(..)) value — typically when parsing clock state persisted by a newer jj version or supplied via fsmonitor config/API that includes SCM-aware clock data, then converting it for the Watchman query.
Common situations: Downgrading jj after a newer version persisted an SCM-aware clock in repo state; sharing a working copy between jj versions where one writes ScmAware clocks; hand-crafting clock specs for testing with the scm-aware variant; Watchman environments where SCM-aware queries were enabled.
Related errors
- Conflicting factory definitions for '{}' factory
- cannot store git submodules
- Conflict registering revset function '{name}'
- ContentHash cannot be derived for unions.
AI-assisted analysis of jj-vcs/jj@6631dbd4a8 (2026-08-28).
Data as JSON: /api/errors/6e5aea0e88fe4f00.
Report an issue: GitHub.