openai/codex · error · std::io::Error
features.multi_agent_v2.default_wait_timeout_ms must be at m
Error message
features.multi_agent_v2.default_wait_timeout_ms must be at most features.multi_agent_v2.max_wait_timeout_ms
What it means
The upper-bound ordering check fires when default_wait_timeout_ms exceeds max_wait_timeout_ms: the default wait would bypass the configured ceiling, so Config::load fails with InvalidInput instead of clamping. It runs after the min/max and default/min checks pass.
Source
Thrown at codex-rs/core/src/config/mod.rs:3740
)?;
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(
std::io::ErrorKind::InvalidInput,
"features.multi_agent_v2.min_wait_timeout_ms must be at most features.multi_agent_v2.max_wait_timeout_ms",
));
}
if multi_agent_v2.default_wait_timeout_ms < multi_agent_v2.min_wait_timeout_ms {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"features.multi_agent_v2.default_wait_timeout_ms must be at least features.multi_agent_v2.min_wait_timeout_ms",
));
}
if multi_agent_v2.default_wait_timeout_ms > multi_agent_v2.max_wait_timeout_ms {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"features.multi_agent_v2.default_wait_timeout_ms must be at most features.multi_agent_v2.max_wait_timeout_ms",
));
}
validate_multi_agent_v2_tool_namespace(multi_agent_v2.tool_namespace.as_deref())?;
let agents_enabled = cfg
.agents
.as_ref()
.and_then(|agents| agents.enabled)
.unwrap_or(true);
let agent_max_threads = cfg
.agents
.as_ref()
.and_then(|agents| agents.max_concurrent_threads_per_session);
if agent_max_threads == Some(0) {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"agents.max_concurrent_threads_per_session must be at least 1",View on GitHub (pinned to 339751715c)
Solutions
- Lower `default_wait_timeout_ms` to at most `max_wait_timeout_ms`.
- Or raise `max_wait_timeout_ms`.
- Or remove `default_wait_timeout_ms` to inherit a valid default.
Example fix
# before [features.multi_agent_v2] default_wait_timeout_ms = 120000 max_wait_timeout_ms = 30000 # after [features.multi_agent_v2] default_wait_timeout_ms = 30000 max_wait_timeout_ms = 120000
Defensive patterns
Strategy: validation
Validate before calling
import tomllib
ma = tomllib.load(open("config.toml", "rb")).get("features", {}).get("multi_agent_v2", {})
d, mx = ma.get("default_wait_timeout_ms"), ma.get("max_wait_timeout_ms")
assert d is None or mx is None or d <= mx, "default_wait_timeout_ms must be <= max_wait_timeout_ms" Try / catch
match config_result {
Err(ref e) if e.kind() == std::io::ErrorKind::InvalidInput
&& e.to_string().contains("default_wait_timeout_ms must be at most") => {
// lower the default or raise the max, then retry
}
other => other,
} Prevention
- When capping max_wait_timeout_ms, re-check the default against the new cap
- Assert the full ordering min<=default<=max in config generation
- Keep timeout knobs in one layer so overrides cannot split the triple
When it happens
Trigger: Any layer combination where default_wait_timeout_ms resolves above max_wait_timeout_ms (e.g. default = 120000, max = 30000).
Common situations: Lowering the max to cap waits while leaving a large default; merging configs where one layer owns the default and another owns the cap.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- features.multi_agent_v2.min_wait_timeout_ms must be at most
- features.multi_agent_v2.default_wait_timeout_ms must be at l
- features.multi_agent_v2.max_concurrent_threads_per_session m
- Environment variable {env_var} for MCP server '{server_name}
- Invalid MCP server name '{server_name}': must match pattern
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/65619f8a0745a314.
Report an issue: GitHub.