{"record":{"id":"c826c7e8675703f3","repo":"gitbutlerapp/gitbutler","slug":"cannot-use-relative-path-outside-a-git-repositor","errorCode":null,"errorMessage":"Cannot use relative --path outside a git repository unless --global is specified.\nUse --global --path <path> for a global installation, use an absolute path, or run from within a repository for local installation.","messagePattern":"Cannot use relative --path outside a git repository unless --global is specified\\.\nUse --global --path <path> for a global installation, use an absolute path, or run from within a repository for local installation\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/skill/mod.rs","lineNumber":1086,"sourceCode":"                    .all(|component| !component.contains('/') && !component.contains('\\\\'))\n        }),\n        \"SkillFile path components must be non-empty and separator-free\"\n    );\n\n    let mut progress = out.progress_channel();\n\n    // Validate flags\n    if detect && custom_path.is_some() {\n        anyhow::bail!(\"Cannot use both --detect and --path options together\");\n    }\n    if ctx.is_none()\n        && !global\n        && let Some(custom) = custom_path.as_deref()\n    {\n        // Without a repository context, only absolute/tilde paths can be resolved without `--global`.\n        let expanded = expand_tilde(custom).unwrap_or_else(|| PathBuf::from(custom));\n        if !expanded.is_absolute() {\n            anyhow::bail!(\n                \"Cannot use relative --path outside a git repository unless --global is specified.\\n\\\n                 Use --global --path <path> for a global installation, use an absolute path, or run from within a repository for local installation.\"\n            );\n        }\n    }\n\n    // Determine installation path(s). Only --detect can yield more than one, when\n    // several GitButler skills share a scope; they are all refreshed together.\n    let agent_default_path = if custom_path.is_none() && !detect {\n        driving_agent.and_then(agent_default_install_path)\n    } else {\n        None\n    };\n    let installed_for_driving_agent = agent_default_path.is_some();\n    let install_paths = if let Some(custom) = custom_path {\n        vec![resolve_custom_path(&custom, ctx, global)?]\n    } else if detect {\n        detect_install_paths(ctx, global)?","sourceCodeStart":1068,"sourceCodeEnd":1104,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/skill/mod.rs#L1068-L1104","documentation":"A relative --path for a local install is anchored at the discovered repository. Outside a git repository (ctx is None) with no --global, there is no anchor for a relative path, so install refuses it. Tilde paths are expanded before the check (expand_tilde), so `~/...` counts as absolute and is accepted.","triggerScenarios":"`cd ~ && but skill install --path skills/gitbutler` - relative path, no repo context, no --global flag.","commonSituations":"Install scripts run from arbitrary directories, users intending a global install but forgetting --global, automation assuming the cwd is always the repo.","solutions":["Use an absolute path: `but skill install --path /home/me/.claude/skills`","Use a tilde path: `but skill install --path ~/.claude/skills` (expanded to absolute)","Add --global: `but skill install --global --path <path>`","Run the command from inside a git repository"],"exampleFix":"$ but skill install --path skills/gb       # fails outside a repo\n$ but skill install --path ~/.claude/skills # tilde counts as absolute","handlingStrategy":"validation","validationCode":"let expanded = shellexpand::tilde(path).to_string(); // or manual ~ expansion\nlet p = std::path::Path::new(&expanded);\nif !p.is_absolute() && !in_git_worktree(&cwd) {\n    // add --global or canonicalize: std::fs::canonicalize / absolutize against cwd\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Absolutize (and expand ~) before passing --path","Treat relative --path as repo-anchored by contract","In scripts, derive paths from a known root instead of user input"],"tags":["cli","path","filesystem","skill","scope"],"backgroundTag":"relative-path-unresolvable","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}