{"record":{"id":"2c112afd2009e58a","repo":"nikivdev/code","slug":"ssh-mode-is-forced-but-no-key-is-available-run-f","errorCode":null,"errorMessage":"SSH mode is forced but no key is available. Run `f ssh setup` or `f ssh unlock` (error: {})","messagePattern":"SSH mode is forced but no key is available\\. Run `f ssh setup` or `f ssh unlock` \\(error: (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/repos.rs","lineNumber":70,"sourceCode":"        Some(ReposAction::HomeBranchStatus(opts)) => run_home_branch_status(opts),\n        Some(ReposAction::BootstrapHomeBranch(opts)) => run_bootstrap_home_branch(opts),\n        Some(ReposAction::MigrateHomeBranch(opts)) => run_migrate_home_branch(opts),\n        Some(ReposAction::Create(opts)) => publish::run_github(opts),\n        Some(ReposAction::Capsule(opts)) => repo_capsule::run_capsule(opts),\n        Some(ReposAction::Alias(cmd)) => repo_capsule::run_alias(cmd),\n        None => fuzzy_select_repo(),\n    }\n}\n\n/// Clone into the current working directory (git clone style destination behavior).\npub fn clone_git_like(opts: CloneOpts) -> Result<()> {\n    ssh::ensure_ssh_env();\n    let mode = ssh::ssh_mode();\n    if matches!(mode, ssh::SshMode::Force) && !ssh::has_identities() {\n        match ssh_keys::ensure_default_identity(24) {\n            Ok(()) => {}\n            Err(err) => {\n                bail!(\n                    \"SSH mode is forced but no key is available. Run `f ssh setup` or `f ssh unlock` (error: {})\",\n                    err\n                );\n            }\n        }\n    }\n\n    let clone_url = resolve_git_like_clone_url(&opts.url)?;\n    let mut cmd = Command::new(\"git\");\n    cmd.arg(\"clone\").arg(&clone_url);\n    if let Some(dir) = opts.directory {\n        cmd.arg(dir);\n    }\n\n    let status = cmd\n        .stdin(Stdio::inherit())\n        .stdout(Stdio::inherit())\n        .stderr(Stdio::inherit())","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/repos.rs#L52-L88","documentation":"clone_git_like enforces SSH policy before cloning: if ssh_mode() reports Force but no SSH identities exist, it attempts to generate/ensure a default key; if that also fails, it bails with this message including the underlying error. It tells the user exactly which commands restore an available key.","triggerScenarios":"`f` clone with SSH mode forced while `ssh::has_identities()` is false AND ssh_keys::ensure_default_identity(24) returns Err (e.g. ssh-agent unavailable, keychain unlock failure, permission error writing the key).","commonSituations":"Fresh machine with no SSH key set up; agent not running / key not loaded after reboot; encrypted key that was never unlocked; forced SSH config pointing at Git remotes on a machine without keys.","solutions":["Run `f ssh setup` to create/configure a default SSH key","Run `f ssh unlock` if you have an existing encrypted key that needs unlocking","Verify `ssh-add -l` shows a key; start the agent (`eval \"$(ssh-agent)\"`) and add the key","Test with `ssh -T git@github.com` to confirm SSH works before cloning"],"exampleFix":"// before\nf clone git@github.com:org/repo.git  // fails: forced SSH, no key\n// after\nf ssh setup\nf clone git@github.com:org/repo.git","handlingStrategy":"validation","validationCode":"const { execSync } = require(\"child_process\");\nfunction hasSshIdentity() {\n  try { return execSync(\"ssh-add -l\", { stdio: [\"ignore\", \"pipe\", \"ignore\"] }).toString().trim().length > 0; }\n  catch { return false; }\n}\nif (!hasSshIdentity()) throw new Error(\"no SSH identity; run `f ssh setup` before cloning\");","typeGuard":null,"tryCatchPattern":"try {\n  run([\"f\", \"clone\", url]);\n} catch (e) {\n  if (String(e).includes(\"SSH mode is forced but no key\")) {\n    console.error(\"Run `f ssh setup` or `f ssh unlock`, then retry the clone.\");\n  } else throw e;\n}","preventionTips":["Run `f ssh setup` once on every new machine before using forced SSH mode","Keep ssh-agent running and keys loaded after reboots (`ssh-add`)","Check `ssh-add -l` shows a key before scripted clone operations"],"tags":["ssh","git","clone","keys"],"backgroundTag":"missing-ssh-key","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}