openai/codex · error · anyhow::Error

unknown environment shell `{name}`

Error message

unknown environment shell `{name}`

What it means

Shell::from_environment_shell_info converts environment-provided shell info (a name + path pair, codex_exec_server::ShellInfo) into a Shell. It accepts an exact-match allowlist of lowercase names: zsh, bash, powershell, sh, cmd. Any other name string bails with this error. It is a strict value-validation failure on the wire/environment data, not a lookup of the binary itself.

Source

Thrown at codex-rs/core/src/shell.rs:69

impl From<DetectedShell> for Shell {
    fn from(detected: DetectedShell) -> Self {
        Self {
            shell_type: detected.shell_type,
            shell_path: detected.shell_path,
        }
    }
}

impl Shell {
    pub(crate) fn from_environment_shell_info(shell_info: ShellInfo) -> anyhow::Result<Self> {
        let shell_type = match shell_info.name.as_str() {
            "zsh" => ShellType::Zsh,
            "bash" => ShellType::Bash,
            "powershell" => ShellType::PowerShell,
            "sh" => ShellType::Sh,
            "cmd" => ShellType::Cmd,
            name => anyhow::bail!("unknown environment shell `{name}`"),
        };

        Ok(Self {
            shell_type,
            shell_path: PathBuf::from(shell_info.path),
        })
    }
}

#[cfg(all(test, unix))]
fn ultimate_fallback_shell() -> Shell {
    codex_shell_command::shell_detect::ultimate_fallback_shell().into()
}

pub fn get_shell_by_model_provided_path(shell_path: &PathBuf) -> Shell {
    codex_shell_command::shell_detect::get_shell_by_model_provided_path(shell_path).into()
}

View on GitHub (pinned to 339751715c)

Solutions

  1. Set the environment to a supported shell: export SHELL=/bin/bash (or /bin/zsh), or chsh -s /bin/zsh, then restart the session
  2. Normalize the name before conversion: map "pwsh"→"powershell" and lowercase the string at the source that builds ShellInfo
  3. If you control the exec server, only report one of the five supported names
  4. File/support adding the shell to the allowlist in shell.rs if it is a legitimate new shell type

Example fix

// before — environment reports PowerShell Core as "pwsh"
let shell = Shell::from_environment_shell_info(ShellInfo { name: "pwsh".into(), path: pwsh_path })?; // unknown environment shell `pwsh`

// after — normalize to the accepted name
let name = match info.name.as_str() { "pwsh" | "powershell" => "powershell", n => n }.to_string();
let shell = Shell::from_environment_shell_info(ShellInfo { name, path: pwsh_path })?;
// (or simply: export SHELL=/bin/zsh in the user environment)
Defensive patterns

Strategy: type-guard

Validate before calling

const SUPPORTED: &[&str] = &["zsh", "bash", "powershell", "sh", "cmd"];
if !SUPPORTED.contains(&shell_info.name.as_str()) {
    return normalise_or_reject(shell_info); // map "pwsh"→"powershell", else fall back to SHELL env
}

Type guard

fn is_supported_shell_name(name: &str) -> bool {
    matches!(name, "zsh" | "bash" | "powershell" | "sh" | "cmd")
}

Try / catch

match Shell::from_environment_shell_info(info.clone()) {
    Ok(shell) => shell,
    Err(e) if e.to_string().contains("unknown environment shell") => {
        Shell::from_environment_shell_info(normalize_shell_name(info))?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling from_environment_shell_info with ShellInfo.name set to anything outside {zsh, bash, powershell, sh, cmd} — e.g. "fish", "nu", "pwsh", "dash", "tcsh", "xonsh", or a capitalized variant like "Zsh".

Common situations: User's login shell (via SHELL or exec-server environment reporting) is fish, nushell, or another non-listed shell; PowerShell Core reported as "pwsh" instead of "powershell"; a custom exec-server or harness sending its own shell naming scheme; case-sensitive mismatch after an environment-reporting change.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/614bcd8343498822. Report an issue: GitHub.