{"record":{"id":"51f3c67fda436881","repo":"Hmbown/CodeWhale","slug":"gh-not-found","errorCode":null,"errorMessage":"gh not found","messagePattern":"gh not found","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/commands/groups/project/share.rs","lineNumber":163,"sourceCode":"}\n\n/// Write HTML to a secure temp file and keep it alive for upload.\nfn write_temp_html(html: &str) -> Result<tempfile::NamedTempFile, String> {\n    let mut tmp = tempfile::Builder::new()\n        .prefix(\"codewhale-share-\")\n        .suffix(\".html\")\n        .tempfile()\n        .map_err(|e| format!(\"{e}\"))?;\n    tmp.write_all(html.as_bytes()).map_err(|e| format!(\"{e}\"))?;\n    Ok(tmp)\n}\n\n/// Upload a file as a GitHub Gist using the `gh` CLI.\nasync fn upload_gist(path: &Path) -> Result<String, String> {\n    let path_owned = path.to_path_buf();\n    let output = tokio::task::spawn_blocking(move || {\n        let mut cmd = crate::dependencies::Gh::command()\n            .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, \"gh not found\"))?;\n        cmd.args([\n            \"gist\",\n            \"create\",\n            \"--public\",\n            path_owned.to_string_lossy().as_ref(),\n            \"--filename\",\n            \"session-export.html\",\n            \"--desc\",\n            \"codewhale Session Export\",\n        ])\n        .output()\n    })\n    .await\n    .map_err(|join_err| format!(\"gh gist create panicked: {join_err}\"))?\n    .map_err(|e| format!(\"Failed to run `gh gist create`: {e}\"))?;\n\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/commands/groups/project/share.rs#L145-L181","documentation":"`upload_gist` shares a file as a GitHub Gist by shelling out to the `gh` CLI. When the `gh` executable cannot be located on the system, the spawned command construction fails with `NotFound` and this \"gh not found\" error string is propagated to the share flow.","triggerScenarios":"Invoking the project share command (`perform_share` -> `upload_gist`) on a machine where `Gh::command()` cannot find the `gh` binary in PATH.","commonSituations":"GitHub CLI not installed at all; `gh` installed via a version manager whose PATH is not active in the environment running codewhale; running inside a container or service without the CLI.","solutions":["Install the GitHub CLI: e.g. `brew install gh`, `apt install gh`, `winget install GitHub.cli`, or see https://cli.github.com.","Verify installation with `gh --version` in the same shell/environment codewhale runs in (PATH must contain it).","If `gh` is installed via a non-default prefix, add its directory to PATH (e.g. `export PATH=\"$HOME/.local/bin:$PATH\"`).","Authenticate once installed: `gh auth login` — the share step also needs a valid GitHub session."],"exampleFix":"// before: error at share time\nlet output = tokio::task::spawn_blocking(move || {\n    let mut cmd = crate::dependencies::Gh::command()\n        .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, \"gh not found\"))?;\n// after (user fix, terminal)\n$ brew install gh && gh auth login\n$ codewhale   # share again","handlingStrategy":"fallback","validationCode":"// caller pre-check before invoking share\nfn gh_available() -> bool {\n    std::process::Command::new(\"gh\").arg(\"--version\").output()\n        .map(|o| o.status.success()).unwrap_or(false)\n}\nif !gh_available() { eprintln!(\"Install the GitHub CLI (gh) first.\"); }","typeGuard":"fn gh_binary_present() -> bool {\n    std::env::var_os(\"PATH\")\n        .map(|p| std::env::split_paths(&p).any(|d| {\n            #[cfg(unix)] { d.join(\"gh\").is_file() }\n            #[cfg(windows)] { d.join(\"gh.exe\").is_file() }\n        }))\n        .unwrap_or(false)\n}","tryCatchPattern":"match perform_share(path).await {\n    Err(msg) if msg.contains(\"gh not found\") => {\n        eprintln!(\"gh CLI missing. Install it (https://cli.github.com), run `gh auth login`, then retry.\");\n    }\n    Err(msg) => eprintln!(\"share failed: {msg}\"),\n    Ok(url) => println!(\"shared: {url}\"),\n}","preventionTips":["Install gh and keep it on PATH in every environment that runs codewhale (shell, CI, containers).","Run `gh auth login` once per machine; expired sessions surface separately.","After installing version-manager-managed tools, refresh PATH in the same shell.","Add a doctor/startup check that verifies required external binaries."],"tags":["cli","missing-binary","github","share"],"backgroundTag":"command-not-found","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}