wezterm/wezterm · error · anyhow::Error

username not present in config

Error message

username not present in config

What it means

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.

Source

Thrown at wezterm-ssh/src/sessioninner.rs:119

            _ => anyhow::bail!(
                "invalid wezterm_ssh_backend value: {}, expected either `ssh2` or `libssh`",
                backend
            ),
        }
    }

    #[cfg(feature = "libssh-rs")]
    fn run_impl_libssh(&mut self) -> anyhow::Result<()> {
        let hostname = self
            .config
            .get("hostname")
            .ok_or_else(|| anyhow!("hostname not present in config"))?
            .to_string();
        let user = self
            .config
            .get("user")
            .ok_or_else(|| anyhow!("username not present in config"))?
            .to_string();
        let port = self
            .config
            .get("port")
            .ok_or_else(|| anyhow!("port is always set in config loader"))?
            .parse::<u16>()?;

        self.tx_event
            .try_send(SessionEvent::Banner(Some(format!(
                "Using libssh-rs to connect to {}@{}:{}",
                user, hostname, port
            ))))
            .context("notifying user of banner")?;

        let sess = libssh_rs::Session::new()?;
        let verbose = self
            .config
            .get("wezterm_ssh_verbose")

View on GitHub (pinned to 3ff7522b96)

Solutions

  1. Use Config::for_host(&host), which fills user (local username) automatically
  2. Or insert "user" explicitly alongside hostname and port
  3. Support an explicit username override like the CLI does (wezterm-ssh examples insert user from a -l/--user flag)

Example fix

// before
let mut config = cfg.for_host("example.com");
config.remove("user");
Session::connect(config).await?; // -> username not present in config

// after
let config = cfg.for_host("example.com"); // user defaults to local username
// or: config.insert("user".into(), "deploy".into());
Session::connect(config).await?;
Defensive patterns

Strategy: validation

Validate before calling

let mut config = cfg.for_host(&host); // sets user from $USER/$USERNAME
if let Some(u) = cli_user { config.insert("user".into(), u); }

Try / catch

Pre-validate: if !config.contains_key("user") insert a default username or return a clear configuration error before connecting.

Prevention

When it happens

Trigger: 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.

Common situations: Embedding wezterm-ssh and hand-rolling the config map; scripts generating config maps from templates that skip the username.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


AI-assisted analysis of wezterm/wezterm@3ff7522b96 (2026-08-20). Data as JSON: /api/errors/f545e3116bdfbaaf. Report an issue: GitHub.