openai/codex · error · std::io::Error

features.multi_agent_v2.max_concurrent_threads_per_session m

Error message

features.multi_agent_v2.max_concurrent_threads_per_session must be at least 1

What it means

resolve_multi_agent_v2_config reads `[features.multi_agent_v2]`, and Config::load enforces max_concurrent_threads_per_session >= 1 because a session must allow at least one concurrent subagent thread. Defaults are non-zero, so hitting this means the key was explicitly set to 0 in some layer.

Source

Thrown at codex-rs/core/src/config/mod.rs:3710

        let model_provider = model_providers
            .get(&model_provider_id)
            .ok_or_else(|| {
                let message = if model_provider_id == LEGACY_OLLAMA_CHAT_PROVIDER_ID {
                    OLLAMA_CHAT_PROVIDER_REMOVED_ERROR.to_string()
                } else {
                    format!("Model provider `{model_provider_id}` not found")
                };
                std::io::Error::new(std::io::ErrorKind::NotFound, message)
            })?
            .clone();

        let shell_environment_policy = cfg.shell_environment_policy.into();
        let allow_login_shell = cfg.allow_login_shell.unwrap_or(true);

        let history = cfg.history.unwrap_or_default();

        if multi_agent_v2.max_concurrent_threads_per_session == 0 {
            return Err(std::io::Error::new(
                std::io::ErrorKind::InvalidInput,
                "features.multi_agent_v2.max_concurrent_threads_per_session must be at least 1",
            ));
        }
        validate_multi_agent_v2_wait_timeout(
            "features.multi_agent_v2.min_wait_timeout_ms",
            multi_agent_v2.min_wait_timeout_ms,
        )?;
        validate_multi_agent_v2_wait_timeout(
            "features.multi_agent_v2.max_wait_timeout_ms",
            multi_agent_v2.max_wait_timeout_ms,
        )?;
        validate_multi_agent_v2_wait_timeout(
            "features.multi_agent_v2.default_wait_timeout_ms",
            multi_agent_v2.default_wait_timeout_ms,
        )?;
        if multi_agent_v2.min_wait_timeout_ms > multi_agent_v2.max_wait_timeout_ms {
            return Err(std::io::Error::new(

View on GitHub (pinned to 339751715c)

Solutions

  1. Set `max_concurrent_threads_per_session = 1` (serial subagent execution) or higher.
  2. Or delete the key to fall back to the built-in default.
  3. If the goal is to turn the feature off, disable the multi_agent_v2 feature rather than zeroing the limit.

Example fix

# before
[features.multi_agent_v2]
max_concurrent_threads_per_session = 0

# after
[features.multi_agent_v2]
max_concurrent_threads_per_session = 1
Defensive patterns

Strategy: validation

Validate before calling

import tomllib
cfg = tomllib.load(open("config.toml", "rb"))
ma = cfg.get("features", {}).get("multi_agent_v2", {})
limit = ma.get("max_concurrent_threads_per_session")
assert limit is None or limit >= 1, "max_concurrent_threads_per_session must be >= 1"

Try / catch

match config_result {
    Err(ref e) if e.kind() == std::io::ErrorKind::InvalidInput
        && e.to_string().contains("features.multi_agent_v2.max_concurrent_threads_per_session") => {
        // clamp to 1 or drop the key, then retry
    }
    other => other,
}

Prevention

When it happens

Trigger: `[features.multi_agent_v2]` with `max_concurrent_threads_per_session = 0` in ~/.codex/config.toml, a project layer, or a managed layer. Fires during Config::load after model-provider resolution.

Common situations: Trying to disable multi-agent v2 by zeroing the limit instead of using the feature's enable switch; copy-paste from tuned examples; a managed layer zeroing the knob globally.

Related errors


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