{"record":{"id":"f545e3116bdfbaaf","repo":"wezterm/wezterm","slug":"username-not-present-in-config","errorCode":null,"errorMessage":"username not present in config","messagePattern":"username not present in config","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"wezterm-ssh/src/sessioninner.rs","lineNumber":119,"sourceCode":"\n            _ => anyhow::bail!(\n                \"invalid wezterm_ssh_backend value: {}, expected either `ssh2` or `libssh`\",\n                backend\n            ),\n        }\n    }\n\n    #[cfg(feature = \"libssh-rs\")]\n    fn run_impl_libssh(&mut self) -> anyhow::Result<()> {\n        let hostname = self\n            .config\n            .get(\"hostname\")\n            .ok_or_else(|| anyhow!(\"hostname not present in config\"))?\n            .to_string();\n        let user = self\n            .config\n            .get(\"user\")\n            .ok_or_else(|| anyhow!(\"username not present in config\"))?\n            .to_string();\n        let port = self\n            .config\n            .get(\"port\")\n            .ok_or_else(|| anyhow!(\"port is always set in config loader\"))?\n            .parse::<u16>()?;\n\n        self.tx_event\n            .try_send(SessionEvent::Banner(Some(format!(\n                \"Using libssh-rs to connect to {}@{}:{}\",\n                user, hostname, port\n            ))))\n            .context(\"notifying user of banner\")?;\n\n        let sess = libssh_rs::Session::new()?;\n        let verbose = self\n            .config\n            .get(\"wezterm_ssh_verbose\")","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/wezterm/wezterm/blob/3ff7522b9617ec920f7fbdb22b57e93d42d93ee9/wezterm-ssh/src/sessioninner.rs#L101-L137","documentation":"run_impl_libssh() requires a \"user\" key in the ssh ConfigMap and errors when absent. for_host() always populates \"user\" (from $USER/$USERNAME, falling back to \"unknown-user\", config.rs:576-578), so hitting this means the map was constructed without for_host() — library/embedder usage, not the standard wezterm path.","triggerScenarios":"Session::connect() with a manually built ConfigMap that sets hostname but omits user; custom integrations that replicate for_host() partially; test fixtures missing the key.","commonSituations":"Embedding wezterm-ssh and hand-rolling the config map; scripts generating config maps from templates that skip the username.","solutions":["Use Config::for_host(&host), which fills user (local username) automatically","Or insert \"user\" explicitly alongside hostname and port","Support an explicit username override like the CLI does (wezterm-ssh examples insert user from a -l/--user flag)"],"exampleFix":"// before\nlet mut config = cfg.for_host(\"example.com\");\nconfig.remove(\"user\");\nSession::connect(config).await?; // -> username not present in config\n\n// after\nlet config = cfg.for_host(\"example.com\"); // user defaults to local username\n// or: config.insert(\"user\".into(), \"deploy\".into());\nSession::connect(config).await?;","handlingStrategy":"validation","validationCode":"let mut config = cfg.for_host(&host); // sets user from $USER/$USERNAME\nif let Some(u) = cli_user { config.insert(\"user\".into(), u); }","typeGuard":null,"tryCatchPattern":"Pre-validate: if !config.contains_key(\"user\") insert a default username or return a clear configuration error before connecting.","preventionTips":["Rely on for_host()'s user default; only override explicitly","Expose a --user/-l style flag in tools built on wezterm-ssh","Test with clean environments (no $USER) to catch missing defaults"],"tags":["ssh","config","libssh","missing-key","wezterm"],"backgroundTag":"missing-config-value","analyzedSha":"3ff7522b9617ec920f7fbdb22b57e93d42d93ee9","analyzedAt":"2026-08-20T04:47:31.434Z","contentChangedAt":"2026-08-20T04:47:31.434Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}