{"record":{"id":"0b3089ab1ba13cc8","repo":"zeroclaw-labs/zeroclaw","slug":"source-path-does-not-exist-source","errorCode":null,"errorMessage":"Source path does not exist: {source}","messagePattern":"Source path does not exist: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-runtime/src/skills/mod.rs","lineNumber":2086,"sourceCode":"                    \"failed to copy skill file from {} to {}\",\n                    src_path.display().to_string(),\n                    dest_path.display()\n                )\n            })?;\n        }\n    }\n\n    Ok(())\n}\n\npub fn install_local_skill_source(\n    source: &str,\n    skills_path: &Path,\n    allow_scripts: bool,\n) -> Result<(PathBuf, usize)> {\n    let source_path = PathBuf::from(source);\n    if !source_path.exists() {\n        anyhow::bail!(\"Source path does not exist: {source}\");\n    }\n\n    let source_path = source_path\n        .canonicalize()\n        .with_context(|| format!(\"failed to canonicalize source path {source}\"))?;\n    let _ = enforce_skill_security_audit(&source_path, allow_scripts)?;\n\n    let name = source_path\n        .file_name()\n        .context(\"Source path must include a directory name\")?;\n    let dest = skills_path.join(name);\n    if dest.exists() {\n        anyhow::bail!(\n            \"Destination skill already exists: {}\",\n            dest.display().to_string()\n        );\n    }\n","sourceCodeStart":2068,"sourceCodeEnd":2104,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/skills/mod.rs#L2068-L2104","documentation":"install_local_skill_source checks PathBuf::from(source).exists() before doing anything else and bails with the literal source string when the path is absent. The check runs before canonicalization, so relative paths resolve against the process's current working directory, and '~' is not expanded.","triggerScenarios":"Typo in the path; a relative path interpreted from a different cwd than the caller assumed; a path containing an unexpanded ~ (no shell expansion happens inside the process); the directory was moved or deleted.","commonSituations":"CLI or tool invoked with ~/skills/foo where nothing expanded the tilde; scripts that cd elsewhere before installing; paths copy-pasted from a different machine.","solutions":["Verify the path exists from the exact directory the process runs in","Use an absolute path","Expand ~ (or reject it) before passing the value to the installer"],"exampleFix":"# before\nzeroclaw skills install ~/skills/my-skill   # tilde never expanded by the process\n\n# after\nzeroclaw skills install \"$HOME/skills/my-skill\"","handlingStrategy":"validation","validationCode":"let p = shellexpand::tilde(source).into_owned(); // or expand manually\nif !std::path::Path::new(&p).exists() {\n    anyhow::bail!(\"skill source not found: {p}\");\n}\ninstall_local_skill_source(&p, &skills_path, allow_scripts)?;","typeGuard":"fn skill_source_exists(source: &str) -> bool {\n    std::path::Path::new(source).exists()\n}","tryCatchPattern":null,"preventionTips":["Normalize to absolute paths at your CLI boundary (expand ~, resolve relatives against a known base)","Validate existence before invoking the installer so your error message can include the cwd","Remember the check is cwd-relative for relative inputs"],"tags":["skills","install","path","filesystem"],"backgroundTag":"path-not-found","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}