BigPizzaV3/CodexPlusPlus · error
model_auto_compact 的模型
Error message
model_auto_compact 的模型 {slug} 百分比无效:{value} What it means
validate_model_auto_compact checks each per-model auto-compact percentage in the model_auto_compact map before it is written into the generated Codex config. parse_compact_percent must accept the value as a valid percentage (e.g. an integer 0-100); if it cannot be parsed, the whole apply is aborted. This guards against writing a malformed compact threshold for a model slug.
Solutions
- Change the value in model_auto_compact to a plain integer percent the parser accepts (e.g. "80" not "80%" or "0.8")
- Verify the exact format parse_compact_percent accepts in crates/codex-plus-core/src/model_suffix.rs and match it
- Remove the offending slug entry from model_auto_compact if per-model compaction is not needed
- Check for whitespace or invisible characters in the imported config value
Example fix
// before
"model_auto_compact": { "deepseek-v4-pro": "85%" }
// after
"model_auto_compact": { "deepseek-v4-pro": "85" } Defensive patterns
Strategy: validation
Validate before calling
function isValidCompactPercent(v) {
const n = Number(v);
return Number.isInteger(n) && n >= 0 && n <= 100 && String(v).trim() === String(n);
}
for (const [slug, v] of Object.entries(settings.model_auto_compact ?? {})) {
if (!isValidCompactPercent(v)) throw new Error(`invalid compact percent for ${slug}: ${v}`);
} Type guard
const isPlainIntString = (v) => /^\d+$/.test(String(v).trim()) && Number(v) >= 0 && Number(v) <= 100;
Prevention
- Store compact thresholds as plain integer strings without '%'
- Clamp/normalize user input in the UI before saving settings
- Validate imported configs before applying them
When it happens
Trigger: Calling apply_relay_profile_to_home_with_switch_rules (or any config-apply path) with a RelayProfile whose model_auto_compact map contains a value that parse_compact_percent rejects — e.g. "85%", "1.5", "abc", "150", empty string, or a percentage with surrounding text.
Common situations: User types a percent sign or decimal into the per-model auto-compact field in the CodexPlusPlus manager UI; config imported from hand-edited JSON with values like "0.9"; a model slug was edited and the value got clobbered.
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.
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/ba74a9080ba03a09.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/relay_config.rs:2130
.ok_or_else(|| anyhow::anyhow!("{field_name} 的模型 {key} 值必须是字符串"))?;
Ok((key.clone(), value.to_string()))
})
.collect()
}
fn validate_model_windows(model_windows: &HashMap<String, String>) -> anyhow::Result<()> {
for (slug, value) in model_windows {
if crate::model_suffix::parse_window_token(value).is_none() {
anyhow::bail!("model_windows 的模型 {slug} 窗口值无效:{value}");
}
}
Ok(())
}
fn validate_model_auto_compact(model_auto_compact: &HashMap<String, String>) -> anyhow::Result<()> {
for (slug, value) in model_auto_compact {
if crate::model_suffix::parse_compact_percent(value).is_none() {
anyhow::bail!("model_auto_compact 的模型 {slug} 百分比无效:{value}");
}
}
Ok(())
}
fn parse_model_metadata_map(metadata_json: &str) -> anyhow::Result<serde_json::Map<String, Value>> {
if metadata_json.trim().is_empty() {
return Ok(serde_json::Map::new());
}
let value: Value = serde_json::from_str(metadata_json)
.map_err(|error| anyhow::anyhow!("model_metadata JSON 解析失败:{error}"))?;
let map = value
.as_object()
.ok_or_else(|| anyhow::anyhow!("model_metadata 必须是 JSON 对象"))?;
for (slug, metadata) in map {
if !metadata.is_object() {
anyhow::bail!("model_metadata 的模型 {slug} 值必须是对象");
}View on GitHub (pinned to b1ed92e5e4)