{"record":{"id":"b84aae5c7263a3bf","repo":"tinyhumansai/openhuman","slug":"source-workspace-matches-current-openhuman-workspa","errorCode":null,"errorMessage":"Source workspace matches current OpenHuman workspace; refusing self-migration","messagePattern":"Source workspace matches current OpenHuman workspace; refusing self-migration","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/config/migration_helpers/core.rs","lineNumber":51,"sourceCode":"    pub stats: MigrationStats,\n    pub warnings: Vec<String>,\n}\n\npub async fn migrate_openclaw_memory(\n    config: &Config,\n    source_workspace: Option<PathBuf>,\n    dry_run: bool,\n) -> Result<MigrationReport> {\n    let source_workspace = resolve_openclaw_workspace(source_workspace)?;\n    if !source_workspace.exists() {\n        bail!(\n            \"OpenClaw workspace not found at {}. Provide a valid source workspace.\",\n            source_workspace.display()\n        );\n    }\n\n    if paths_equal(&source_workspace, &config.workspace_dir) {\n        bail!(\"Source workspace matches current OpenHuman workspace; refusing self-migration\");\n    }\n\n    let mut stats = MigrationStats::default();\n    let entries = collect_source_entries(&source_workspace, &mut stats)?;\n    let mut warnings = Vec::new();\n\n    if entries.is_empty() {\n        warnings.push(format!(\n            \"No importable memory found in {}\",\n            source_workspace.display()\n        ));\n        warnings.push(\"Checked for: memory/brain.db, MEMORY.md, memory/*.md\".to_string());\n        return Ok(MigrationReport {\n            source_workspace,\n            target_workspace: config.workspace_dir.clone(),\n            dry_run,\n            stats,\n            warnings,","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/config/migration_helpers/core.rs#L33-L69","documentation":"Self-migration guard in `migrate_openclaw_memory`: after resolving the source workspace, `paths_equal` compares it with `config.workspace_dir` (the active OpenHuman workspace) and bails on a match. Importing a workspace onto itself would re-import the app's own memory into itself and could duplicate or corrupt data, so the operation is refused up front.","triggerScenarios":"Passing a source path that equals the active OpenHuman workspace, or having `config.workspace_dir` (e.g. via OPENHUMAN_WORKSPACE) pointed at `~/.openclaw/workspace` so the default resolution collides with the destination.","commonSituations":"'Migrate in place' setups where the OpenHuman workspace was deliberately pointed at the old app's data dir; symlinked or aliased paths that canonicalize to the same directory; copied workspaces that keep the same location.","solutions":["Point `source_workspace` at the original OpenClaw data location, distinct from the OpenHuman workspace.","If an in-place import is truly wanted, copy the source tree to a temp directory and migrate from the copy.","Check env/config overrides (OPENHUMAN_WORKSPACE, workspace_dir) that make the two paths resolve identically and retarget them."],"exampleFix":"# before — OpenHuman workspace pointed at the source data\nOPENHUMAN_WORKSPACE=~/.openclaw/workspace openhuman-core ...\n\n# after — separate destination, then migrate\nOPENHUMAN_WORKSPACE=~/.openhuman/users/me/workspace openhuman-core \\\n  config.migrate_openclaw_memory --source ~/.openclaw/workspace","handlingStrategy":"validation","validationCode":"let src = src.canonicalize()?;\nlet dst = config.workspace_dir.canonicalize()?;\nif src == dst {\n    // source and destination are the same tree — refuse before calling migrate\n    return Ok(None);\n}\nlet report = migrate_openclaw_memory(&config, Some(src), dry_run).await?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never point the migration source at the active OpenHuman workspace","Watch OPENHUMAN_WORKSPACE overrides that can alias the source path","For in-place imports, copy the source tree to a temp dir and migrate from the copy"],"tags":["migration","openclaw","workspace","self-migration-guard","path-validation"],"backgroundTag":"migration-source-conflict","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}