{"record":{"id":"dea0fce0a0ae4faf","repo":"nikivdev/code","slug":"fish-shell-required-run-chsh-s","errorCode":null,"errorMessage":"fish shell required. Run:\n  chsh -s {}","messagePattern":"fish shell required\\. Run:\n  chsh -s (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/health.rs","lineNumber":84,"sourceCode":"        println!(\n            \"ℹ️  run internal repo not detected at {}\",\n            run_internal.display()\n        );\n    }\n\n    println!(\n        \"ℹ️  run shortcuts: f r <task>, f ri <task>, f rp <project> <task>, f rip <project> <task>\"\n    );\n\n    Ok(())\n}\n\nfn ensure_fish_shell() -> Result<()> {\n    let shell = env::var(\"SHELL\").unwrap_or_default();\n    if !shell.contains(\"fish\") {\n        let fish = which::which(\"fish\")\n            .context(\"fish is required; install it and ensure it is on PATH\")?;\n        bail!(\"fish shell required. Run:\\n  chsh -s {}\", fish.display());\n    }\n    Ok(())\n}\n\nfn ensure_fish_flow_init() -> Result<()> {\n    if which::which(\"f\").is_ok() {\n        return Ok(());\n    }\n\n    let config_path = fish_config_path()?;\n    let content = fs::read_to_string(&config_path).unwrap_or_default();\n    if content.contains(\"# flow:start\") {\n        return Ok(());\n    }\n\n    println!(\n        \"⚠ flow fish integration missing in {}. Ensure the `f` binary is on PATH, then run: f shell-init fish\",\n        config_path.display()","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/health.rs#L66-L102","documentation":"`ensure_fish_shell` is a health/startup check that reads the `SHELL` environment variable and requires it to contain \"fish\". If not, it locates the fish binary with `which` and bails telling the user to switch their login shell via `chsh -s <path>`. The check verifies the user's configured login shell, not merely that fish exists.","triggerScenarios":"Running the tool with `$SHELL` set to bash/zsh/sh (or unset, defaulting to empty string) even though fish is installed.","commonSituations":"Running from a non-interactive context (IDE terminal, cron, CI) where SHELL is inherited as /bin/bash; fresh machines where fish was installed but `chsh` was never run; SSH sessions with a different default shell; calling the tool via `bash -c` from a script.","solutions":["Change your login shell to fish as the message suggests: `chsh -s $(which fish)` (then re-login)","For a one-off run, set the variable: `SHELL=$(which fish) f <command>`","Verify the variable: `echo $SHELL` — it must point at a path containing \"fish\"","If the binary path itself doesn't contain the substring 'fish' (custom install path), symlink or reinstall fish to a standard path like /usr/bin/fish"],"exampleFix":"# before\necho $SHELL   # /bin/bash\n# after\nchsh -s /usr/bin/fish\n# re-login, then:\necho $SHELL   # /usr/bin/fish","handlingStrategy":"validation","validationCode":"let shell = std::env::var(\"SHELL\").unwrap_or_default();\nif !shell.contains(\"fish\") {\n    eprintln!(\"this tool requires fish as your login shell; run: chsh -s $(which fish)\");\n    std::process::exit(1);\n}","typeGuard":"fn is_fish_shell() -> bool {\n    std::env::var(\"SHELL\")\n        .map(|s| s.contains(\"fish\"))\n        .unwrap_or(false)\n}","tryCatchPattern":"match ensure_fish_shell() {\n    Err(e) if e.to_string().contains(\"fish shell required\") => {\n        eprintln!(\"{e}\");\n        eprintln!(\"or run once with: SHELL=$(which fish) f <cmd>\");\n    }\n    r => r?,\n}","preventionTips":["Run `chsh -s $(which fish)` right after installing fish, then re-login","Set SHELL explicitly in scripts/CI that invoke the tool","Check `echo $SHELL` before running the tool in unfamiliar environments","Prefer running the tool from an interactive fish session"],"tags":["shell","fish","environment","configuration"],"backgroundTag":"missing-required-shell","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}