{"record":{"id":"f776d865912307e0","repo":"tinyhumansai/openhuman","slug":"hermes-workspace-not-found-at-provide-a-valid","errorCode":null,"errorMessage":"Hermes workspace not found at {}. Provide a valid source workspace.","messagePattern":"Hermes workspace not found at (.+?)\\. Provide a valid source workspace\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/config/migration_helpers/core.rs","lineNumber":319,"sourceCode":"            \"hermes_user_profile\",\n            MemoryCategory::Custom(\"user_profile\".to_string()),\n        ),\n        (\n            \"SOUL.md\",\n            \"hermes_persona\",\n            MemoryCategory::Custom(\"persona\".to_string()),\n        ),\n    ]\n}\n\npub async fn migrate_hermes_memory(\n    config: &Config,\n    source_workspace: Option<PathBuf>,\n    dry_run: bool,\n) -> Result<MigrationReport> {\n    let source_workspace = resolve_hermes_workspace(source_workspace)?;\n    if !source_workspace.exists() {\n        bail!(\n            \"Hermes 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 mut warnings = Vec::new();\n    let mut entries = Vec::new();\n\n    for (filename, key, category) in hermes_file_mappings() {\n        let path = source_workspace.join(filename);\n        if !path.exists() {\n            warnings.push(format!(\n                \"{filename} not found in {}\",","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/config/migration_helpers/core.rs#L301-L337","documentation":"`migrate_hermes_memory` resolves the Hermes source workspace — explicit argument, else `~/.hermes` (`%LOCALAPPDATA%\\hermes` on Windows) — and refuses to run when the path does not exist. Like the OpenClaw guard, it will not fabricate an empty migration from a missing source; the message echoes the resolved path.","triggerScenarios":"Running the Hermes migration on a machine where Hermes is not installed at the default location, or with an explicit path that is wrong, on an unmounted volume, or owned by a different user.","commonSituations":"Migration offered or run on machines that never had Hermes installed; wrong user account (home differs); data on an unmounted or container-uncmounted volume.","solutions":["Pass the correct Hermes data directory explicitly to the migration call.","Restore or mount the Hermes data at the default location and retry.","Skip the migration when Hermes was never installed on this machine."],"exampleFix":"// before\nlet report = migrate_hermes_memory(&config, None, false).await?;\n\n// after — explicit, verified source\nlet src = PathBuf::from(\"/data/hermes\");\nif !src.is_dir() { anyhow::bail!(\"no Hermes data at {}\", src.display()); }\nlet report = migrate_hermes_memory(&config, Some(src), false).await?;","handlingStrategy":"validation","validationCode":"let src = source_path.unwrap_or_else(|| hermes_default_path()); // ~/.hermes or %LOCALAPPDATA%/hermes\nif !src.is_dir() {\n    // Hermes not present on this machine — skip the migration instead of calling it\n    return Ok(None);\n}\nlet report = migrate_hermes_memory(&config, Some(src), dry_run).await?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check the source path exists before invoking the migration","Pass explicit source paths in automation","Skip the migration when Hermes was never installed"],"tags":["migration","hermes","workspace","path-not-found"],"backgroundTag":"path-not-found","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}