{"record":{"id":"b69acd18092fde35","repo":"gitbutlerapp/gitbutler","slug":"could-not-detect-an-existing-gitbutler-skill-insta","errorCode":null,"errorMessage":"Could not detect an existing GitButler skill installation.\nRun `but skill install` to create one, or use `--path <dir>` to choose a location.","messagePattern":"Could not detect an existing GitButler skill installation\\.\nRun `but skill install` to create one, or use `--path <dir>` to choose a location\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/skill/mod.rs","lineNumber":832,"sourceCode":"/// Returns every GitButler skill in the highest-priority scope that has one\n/// (local before global), so `--detect` refreshes them all instead of forcing a\n/// choice between them. Filtering to a single scope keeps a repo-local `--detect`\n/// from reaching into global installs.\nfn detect_install_paths(ctx: Option<&mut Context>, global: bool) -> Result<Vec<PathBuf>> {\n    let installations = find_all_installations(ctx, true, !global)?;\n\n    for scope in [SCOPE_LOCAL, SCOPE_GLOBAL] {\n        let paths: Vec<PathBuf> = installations\n            .iter()\n            .filter(|(_, _, s)| *s == scope)\n            .map(|(path, _, _)| path.clone())\n            .collect();\n        if !paths.is_empty() {\n            return Ok(paths);\n        }\n    }\n\n    anyhow::bail!(\n        \"Could not detect an existing GitButler skill installation.\\n\\\n         Run `but skill install` to create one, or use `--path <dir>` to choose a location.\"\n    )\n}\n\nfn prompt_for_install_scope(\n    input: &mut crate::utils::InputOutputChannel<'_>,\n    progress: &mut impl std::io::Write,\n) -> Result<InstallScope> {\n    let t = theme::get();\n    writeln!(progress)?;\n    writeln!(\n        progress,\n        \"{}\",\n        t.important.paint(\"Select installation scope:\")\n    )?;\n    writeln!(progress)?;\n","sourceCodeStart":814,"sourceCodeEnd":850,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/skill/mod.rs#L814-L850","documentation":"detect_install_paths backs the --detect flag of `but skill update`/`but skill status`: it collects installation paths from the local (repo) scope and the global scope, in that priority. If neither scope contains a GitButler skill installation, there is nothing to detect or update and the command bails with instructions to install or pass --path.","triggerScenarios":"Calling `but skill update --detect` before `but skill install` was ever run, or after the skill directory (e.g. .claude/skills/gitbutler or the global equivalent) was deleted or moved to a non-default location.","commonSituations":"Fresh machine where the skill was never installed, cleanup scripts that wiped dotfile directories, installations renamed so detection scans miss them.","solutions":["Run `but skill install` to create an installation first, then retry --detect","Pass `--path <dir>` pointing at the existing moved/renamed installation","Reinstall at the default location so future `--detect` updates work"],"exampleFix":"$ but skill update --detect   # fails: nothing installed\n$ but skill install            # create one\n$ but skill update --detect    # now succeeds","handlingStrategy":"validation","validationCode":"// verify an installation exists before `update --detect`\nlet installed = [\".claude/skills/gitbutler\", /* global path */]\n    .iter()\n    .any(|p| std::path::Path::new(p).join(\"SKILL.md\").exists());\nif !installed { /* run `but skill install` instead of `update --detect` */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run `but skill install` before scripting `but skill update --detect`","Keep the skill at the default path so --detect finds it","Pin --path in automation to avoid detection entirely"],"tags":["cli","skill","detect","install","update"],"backgroundTag":"installation-not-found","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}