BigPizzaV3/CodexPlusPlus · critical
config.toml TOML 解析失败:
Error message
config.toml TOML 解析失败:{error} What it means
The config.toml loader trims a UTF-8 BOM, treats an empty file as an empty document, and otherwise parses with toml_edit::DocumentMut. When the file content is not valid TOML syntax, the parse error is wrapped as "config.toml TOML 解析失败:{error}". This guards all read/apply operations so they fail fast instead of silently working on a partial document.
Solutions
- Read the toml_edit error detail after 解析失败: in the message — it gives line/column; fix that exact syntax problem in config.toml.
- Run the file through a TOML validator/parser to enumerate all syntax errors before retrying.
- Restore config.toml from backup or from codex defaults and re-apply the profile.
- Check for leftover git merge-conflict markers and stray characters near the reported line.
Example fix
// before (config.toml) model = "gpt-5 model_providers = [openai] // after (config.toml) model = "gpt-5" [model_providers.openai] base_url = "https://api.openai.com/v1"
Defensive patterns
Strategy: try-catch
Validate before calling
fn config_toml_is_valid(path: &str) -> bool {
std::fs::read_to_string(path)
.map(|c| c.trim_start_matches('\u{feff}').parse::<toml_edit::DocumentMut>().is_ok())
.unwrap_or(false)
} Try / catch
match apply_relay_profile_to_home_with_switch_rules(...) {
Err(e) if e.to_string().contains("TOML 解析失败") => {
// restore config.toml from backup, or surface the toml_edit line/column to the user
}
other => other?,
} Prevention
- Back up config.toml before any manual or scripted edit
- Use a TOML-aware editor/plugin with syntax checking
- Never paste JSON into config.toml
- Resolve git merge conflicts in config.toml before applying profiles
- Strip stray BOM/garbage; the loader only tolerates a leading BOM on an otherwise valid file
When it happens
Trigger: Any call that reads config.toml (apply_relay_profile_to_home_with_switch_rules, merge/switch flows) when the file contains syntactically invalid TOML: unclosed brackets, duplicate keys, unterminated strings, or wrong indentation for multi-line strings.
Common situations: Manual edits with a non-TOML-aware editor, paste of JSON instead of TOML, copy-paste losing quotes/brackets, merge conflict markers (<<<<<<<) left in the file, or an editor writing a BOM-plus-garbage file.
Related errors
- config.toml TOML 解析失败:
- Dream Skin theme backup belongs to a different config.toml
- JSON 解析失败:
- 必须是 TOML table
- model_providers. 必须是 TOML table
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/684f1b8d75003fc6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/relay_config.rs:1409
fn is_custom_provider_id(provider: &str) -> bool {
!provider.is_empty() && !RESERVED_MODEL_PROVIDER_IDS.contains(&provider)
}
fn provider_table_exists(doc: &DocumentMut, provider_id: &str) -> bool {
doc.get("model_providers")
.and_then(Item::as_table)
.and_then(|table| table.get(provider_id))
.is_some()
}
fn parse_toml_document(contents: &str) -> anyhow::Result<DocumentMut> {
let contents = contents.trim_start_matches('\u{feff}');
if contents.trim().is_empty() {
Ok(DocumentMut::new())
} else {
contents
.parse::<DocumentMut>()
.map_err(|error| anyhow::anyhow!("config.toml TOML 解析失败:{error}"))
}
}
fn remove_provider_specific_common_keys(table: &mut dyn TableLike) {
for key in PROVIDER_SPECIFIC_COMMON_ROOT_KEYS {
table.remove(key);
}
let sensitive_keys: Vec<String> = table
.iter()
.map(|(key, _)| key.to_string())
.filter(|key| is_provider_credential_root_key(key))
.collect();
for key in sensitive_keys {
table.remove(&key);
}
table.remove("model_providers");
}
View on GitHub (pinned to b1ed92e5e4)