zeroclaw-labs/zeroclaw · error · anyhow::Error

Source workspace matches current ZeroClaw workspace; refusin

Error message

Source workspace matches current ZeroClaw workspace; refusing self-migration

What it means

After confirming the source workspace exists, migrate_openclaw_memory compares it against config.data_dir (the current ZeroClaw data directory) with paths_equal and refuses to continue if they are the same. The guard exists because migration reads from the source and writes into ZeroClaw's store; when they are one directory the migration would read and rewrite its own output, corrupting data.

Source

Thrown at crates/zeroclaw-runtime/src/migration.rs:41

    renamed_conflicts: usize,
}

pub async fn migrate_openclaw_memory(
    config: &Config,
    source_workspace: Option<PathBuf>,
    dry_run: bool,
    reindex: bool,
) -> Result<()> {
    let source_workspace = resolve_openclaw_workspace(source_workspace)?;
    if !source_workspace.exists() {
        bail!(
            "OpenClaw workspace not found at {}. Pass --source <path> if needed.",
            source_workspace.display()
        );
    }

    if paths_equal(&source_workspace, &config.data_dir) {
        bail!("Source workspace matches current ZeroClaw workspace; refusing self-migration");
    }

    let mut stats = MigrationStats::default();
    let entries = collect_source_entries(&source_workspace, &mut stats)?;

    if entries.is_empty() {
        println!(
            "No importable memory found in {}",
            source_workspace.display()
        );
        println!("Checked for: memory/brain.db, MEMORY.md, memory/*.md");
        return Ok(());
    }

    if dry_run {
        println!("🔎 Dry run: OpenClaw migration preview");
        println!("  Source: {}", source_workspace.display().to_string());
        println!("  Target: {}", config.data_dir.display().to_string());

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Point --source at the original OpenClaw workspace, keeping it distinct from ZeroClaw's data dir
  2. Check the current data dir (zeroclaw config get data_dir or equivalent) and make sure the two paths differ
  3. If the data genuinely overlaps, move one workspace to a separate directory first, then re-run
  4. If you already manually merged data, skip migration — nothing left to import

Example fix

# before
data_dir = "/home/user/.openclaw"   # zeroclaw.toml
zeroclaw migrate-memory --source /home/user/.openclaw

# after
data_dir = "/home/user/.zeroclaw"
zeroclaw migrate-memory --source /home/user/.openclaw
Defensive patterns

Strategy: validation

Validate before calling

let src = resolve_openclaw_workspace(source_workspace.clone())?;
if paths_equal(&src, &config.data_dir) {
    // refuse early with a targeted message; source and destination must be distinct stores
    anyhow::bail!("source equals data_dir; refusing to migrate in place");
}

Try / catch

Err(e) if e.to_string().contains("refusing self-migration") => {
    // config error: separate the two workspaces, then re-run; never bypass
}

Prevention

When it happens

Trigger: Passing --source that resolves to the ZeroClaw data dir itself; config.data_dir changed to point at the old OpenClaw directory (e.g. to "adopt" it in place); symlinks or different spellings of the same path (paths_equal normalizes, so /a/b vs /a/./b still collide).

Common situations: Adopt in place" setups where users repoint data_dir at OpenClaw's folder and then run migration; container mounts that map both workspaces to the same volume; copy-pasting a tutorial's --source that happens to equal the install's data dir.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/7a9c3f04f53a9c7b. Report an issue: GitHub.