nikivdev/code · error

absolute paths are not supported in sync links: {}

Error message

absolute paths are not supported in sync links: {}

What it means

normalize_dest_rel validates sync-link destination paths in the home dotfiles manager. Paths may be relative or use the `~/` prefix; any other absolute path (e.g. /etc/..., /home/...) is rejected because links are always created relative to the managed home directory. This keeps the sync manifest portable across machines and users.

Source

Thrown at src/home.rs:285

            format!(
                "failed to move {} to {}",
                dest.display(),
                archive_path.display()
            )
        })?;
        moved.push(archive_path);
    }

    Ok(moved)
}

fn normalize_dest_rel(dest: &Path) -> Result<PathBuf> {
    let dest_str = dest.to_string_lossy();
    if let Some(stripped) = dest_str.strip_prefix("~/") {
        return Ok(PathBuf::from(stripped));
    }
    if dest.is_absolute() {
        bail!(
            "absolute paths are not supported in sync links: {}",
            dest.display()
        );
    }
    Ok(dest.to_path_buf())
}

fn is_symlink_to(link: &Path, expected: &Path) -> bool {
    let meta = match fs::symlink_metadata(link) {
        Ok(v) => v,
        Err(_) => return false,
    };
    if !meta.file_type().is_symlink() {
        return false;
    }

    let target = match fs::read_link(link) {
        Ok(v) => v,

View on GitHub (pinned to a747e741ae)

Solutions

  1. Rewrite the dest as a path relative to the home directory
  2. Use the `~/` prefix form (e.g. `~/.config/foo`) which is stripped automatically
  3. Remove the leading `/home/<user>` or `/Users/<user>` portion from the entry

Example fix

// before (home.toml)
[[links]]
dest = "/home/alice/.vimrc"
// after
[[links]]
dest = "~/.vimrc"
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_dest(dest: &str) -> bool {
    dest.starts_with("~/") || !std::path::Path::new(dest).is_absolute()
}

Type guard

fn valid_dest_rel(dest: &Path) -> Option<PathBuf> {
    let s = dest.to_string_lossy();
    if let Some(r) = s.strip_prefix("~/") { return Some(PathBuf::from(r)); }
    if dest.is_absolute() { None } else { Some(dest.to_path_buf()) }
}

Try / catch

match normalize_dest_rel(&dest) {
    Ok(rel) => use(rel),
    Err(e) if e.to_string().starts_with("absolute paths are not supported") => {
        eprintln!("rewrite '{}' relative to $HOME or as ~/-prefixed", dest.display());
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling archive_existing_configs, ensure_link_targets, or validate_setup with a dest entry that is neither `~/`-prefixed nor relative — i.e. dest.is_absolute() is true after the `~/` strip fails.

Common situations: Hand-edited home.toml sync entries with absolute paths copied from another machine; generating config from scripts that emit full paths; migrating configs between users where /home/alice/... was hardcoded.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/a0ee7693f119ad5b. Report an issue: GitHub.