astrid-runtime/astrid · error
legacy source is an active mount: {}
Error message
legacy source is an active mount: {} What it means
retire_tree refuses to delete a legacy source that is itself an active mount point, detected via /proc/self/mountinfo (Linux) or statfs filesystem-id comparison (macOS). Deleting a mounted directory would only clear the mountpoint while leaving the mounted data, so the operation aborts with InvalidData.
Source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:267
io::ErrorKind::AlreadyExists,
format!(
"legacy source changed before retirement: {}",
path.display()
),
));
}
let metadata = fs::symlink_metadata(path)?;
if !metadata.is_dir() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy retirement root is not a directory: {}",
path.display()
),
));
}
if active_mountpoint(path)? {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("legacy source is an active mount: {}", path.display()),
));
}
let device = device_id(&metadata);
for entry in fs::read_dir(path).map_err(io::Error::other)? {
let child = entry.map_err(io::Error::other)?.path();
if protected.iter().any(|candidate| candidate == &child) {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy component source reappeared during ordinary retirement: {}",
child.display()
),
));
}
let child_meta = fs::symlink_metadata(&child).map_err(io::Error::other)?;
if child_meta.file_type().is_symlink() || (!child_meta.is_file() && !child_meta.is_dir()) {View on GitHub (pinned to affd8760f4)
Solutions
- Unmount the mount point (`umount <path>`) so the legacy path is an ordinary directory again, then rerun retirement.
- Move the mount elsewhere; the legacy path must live on the same filesystem as its parent with no mount at or below it.
- If the data genuinely lives on the other volume, migrate it physically into the legacy location (or update config) instead of mounting.
- After unmounting, verify with `findmnt <path>` that nothing is mounted before retrying.
Example fix
# before mount --bind /data/legacy ~/.astrid/legacy/db // after umount ~/.astrid/legacy/db rsync -a /data/legacy/ ~/.astrid/legacy/db/ # physical copy, then migrate
Defensive patterns
Strategy: validation
Validate before calling
// Linux: check the path is not a mount point before migrating
fn is_mountpoint(path: &std::path::Path) -> std::io::Result<bool> {
let canon = std::fs::canonicalize(path)?;
let mi = std::fs::read_to_string("/proc/self/mountinfo")?;
Ok(mi.lines().any(|l| l.split_whitespace().nth(4) == Some(canon.to_str().unwrap_or(""))))
} Try / catch
match retire_tree(path, &expected, &protected) {
Err(e) if e.to_string().contains("is an active mount") => {
eprintln!("unmount {} before migration", path.display());
}
other => other?,
} Prevention
- Keep legacy data as plain directories on one filesystem — no bind mounts, tmpfs, or NFS at legacy paths
- Run `findmnt --target <path>` as a pre-migration check
- On macOS, ensure the home and its parent live on the same volume
When it happens
Trigger: retire_tree -> active_mountpoint(path) returns true because the legacy path is a bind mount, tmpfs, network mount, or (macOS) resides on a different filesystem than its parent. This check runs at the root and recursively at each child (children on a different device raise the sibling boundary error).
Common situations: Users bind-mounting or symlinking-via-mount legacy data from another volume into the old location; Docker/overlay or NFS mounts placed at the legacy path; macOS users whose home is on a different volume than the mount point's parent.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- mountpoint is already registered: {}
- legacy capsule entry has a non-UTF-8 name
- legacy state source crosses a filesystem boundary: {}
- legacy state source is an active mount: {}
- layout cutover record is not a regular file: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/67a825776458ed1a.
Report an issue: GitHub.