BigPizzaV3/CodexPlusPlus · error · anyhow::Error
启动超时必须是正数:
Error message
启动超时必须是正数:{timeout} What it means
build_mcp_toml_body validates the MCP form's startup_timeout_sec field. If the field is non-empty, it is parsed as f64; if the value parses but is zero, negative, NaN or infinite, this bail fires. The library requires startup timeout to be a strictly positive finite number because it is written verbatim into the codex config.toml and a non-positive timeout would be rejected or misbehave at runtime.
Solutions
- Set startup_timeout_sec to a positive number greater than 0 (e.g. 30).
- If the timeout is unknown, leave the field empty/omitted so the default is used instead of 0.
- Trim whitespace and ensure no sign character or scientific notation that evaluates to <= 0 is present.
- If importing JSON, fix the offending server's startup_timeout_sec before import, or accept the per-entry warning and correct it afterwards.
Example fix
// before startup_timeout_sec = 0 // after startup_timeout_sec = 30
Defensive patterns
Strategy: validation
Validate before calling
fn valid_timeout(s: &str) -> bool {
match s.trim().parse::<f64>() {
Ok(v) => v.is_finite() && v > 0.0,
Err(_) => false,
}
} Try / catch
match build_mcp_toml_body(&form) {
Ok(body) => /* ... */,
Err(e) if e.to_string().contains("启动超时") => show_field_error("startup_timeout_sec", format!("{e}")),
Err(e) => return Err(e),
} Prevention
- Clamp the UI input to a positive numeric range before submission
- Leave the field empty instead of entering 0 when no custom timeout is wanted
- Validate numeric fields on blur, not only on save
- Trim input and reject sign characters unless followed by a positive value
When it happens
Trigger: Calling build_mcp_toml_body (directly or via parse_mcp_servers_json) with a form whose startup_timeout_sec is e.g. "0", "-5", "0.0", or a value that parses to NaN/inf (the parse itself failing produces the separate '必须是数字' error).
Common situations: User types 0 or a negative number into the startup-timeout field of the MCP config UI; JSON import carries startup_timeout_sec: 0 copied from another tool; locale/formatter output like "1,5" would hit the sibling numeric error, but "-1" hits this one.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- 官方混合 API 不应在 auth.json 中保存 OPENAI_API_KEY。请清理此供应商的…
- 请填写 API 的模型名称
- Base URL 不能为空
- 上游 Base URL 不能为空
- 图片上游 Base URL 不能为空
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/48d9daf0c91d040f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/mcp_config.rs:217
table["args"] = Item::Value(TomlValue::Array(array));
}
set_string(table, "cwd", &form.cwd);
set_inline_map(table, "env", &form.env);
}
McpTransport::Http => {
set_string(table, "url", &form.url);
set_inline_map(table, "http_headers", &form.http_headers);
set_string(table, "bearer_token", &form.bearer_token);
}
}
let timeout = form.startup_timeout_sec.trim();
if !timeout.is_empty() {
let parsed: f64 = timeout
.parse()
.with_context(|| format!("启动超时必须是数字:{timeout}"))?;
if !parsed.is_finite() || parsed <= 0.0 {
anyhow::bail!("启动超时必须是正数:{timeout}");
}
// 整数写成整数:toml_edit::value(30.0) 会产出 `30.0`,
// 而 codex 那边期望 f64,两种都收,但配置文件里 `30` 更干净。
if parsed.fract() == 0.0 && parsed.abs() < 1e15 {
table["startup_timeout_sec"] = toml_edit::value(parsed as i64);
} else {
table["startup_timeout_sec"] = toml_edit::value(parsed);
}
}
// enabled = true 是默认值,不写进去省得每条都带一行噪音
if !form.enabled {
table["enabled"] = toml_edit::value(false);
}
if !form.extra_toml.trim().is_empty() {
let extra: DocumentMut = form
.extra_tomlView on GitHub (pinned to b1ed92e5e4)