{"record":{"id":"781fe91793979c58","repo":"BigPizzaV3/CodexPlusPlus","slug":"table-name-toml","errorCode":null,"errorMessage":"{table_name} 必须是 TOML 表","messagePattern":"(.+?) 必须是 TOML 表","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/relay_config.rs","lineNumber":1049,"sourceCode":"pub fn upsert_context_entry_in_common_config(\n    common_config: &str,\n    kind: &str,\n    id: &str,\n    toml_body: &str,\n) -> anyhow::Result<String> {\n    let id = id.trim();\n    if id.is_empty() {\n        anyhow::bail!(\"上下文 id 不能为空\");\n    }\n    let table_name = context_table_name(kind)?;\n    let body_doc = parse_toml_document(toml_body)?;\n    let normalized = normalize_duplicate_toml_text(common_config);\n    let mut doc = parse_toml_document(&normalized)?;\n    if !doc.as_table().contains_key(table_name) {\n        doc[table_name] = toml_edit::table();\n    }\n    if doc[table_name].as_table().is_none() {\n        anyhow::bail!(\"{table_name} 必须是 TOML 表\");\n    }\n    doc[table_name][id] = Item::Table(body_doc.as_table().clone());\n    Ok(normalize_optional_toml(doc))\n}\n\npub fn delete_context_entry_from_common_config(\n    common_config: &str,\n    kind: &str,\n    id: &str,\n) -> anyhow::Result<String> {\n    let table_name = context_table_name(kind)?;\n    let normalized = normalize_duplicate_toml_text(common_config);\n    let mut doc = parse_toml_document(&normalized)?;\n    if let Some(table) = doc[table_name].as_table_mut() {\n        table.remove(id.trim());\n        if table.is_empty() {\n            doc.as_table_mut().remove(table_name);\n        }","sourceCodeStart":1031,"sourceCodeEnd":1067,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/relay_config.rs#L1031-L1067","documentation":"After ensuring the target table key exists in the normalized common config, the function checks that the value at table_name is actually a TOML table. If an existing key of that name holds a scalar or array, inserting a sub-table under it is impossible, so the library bails naming the offending table.","triggerScenarios":"Calling upsert_context_entry_in_common_config when the common config already contains e.g. model_context_window = 5 or context = [\"a\"] — a non-table value under the table name returned by context_table_name(kind).","commonSituations":"Hand-edited config.toml where a context section name was overwritten with a plain value; a merge tool flattened a table into a scalar; migrating an older config format into the new schema.","solutions":["Edit config.toml so the key (e.g. [mcp_servers]) is a proper table, removing the scalar/array value","Back up and delete the conflicting scalar key, then retry the upsert","Use delete_context_entry_from_common_config / normalization to clean the malformed section first"],"exampleFix":"// before (config.toml)\nmcp_servers = 3\n// after (config.toml)\n[mcp_servers.my-server]\ncommand = \"foo\"","handlingStrategy":"validation","validationCode":"let doc: toml_edit::DocumentMut = config.parse()?;\nlet table_name = context_table_name(kind)?;\nif let Some(item) = doc.get(table_name) {\n    if item.as_table().is_none() {\n        return Err(anyhow::anyhow!(\"{table_name} 必须是 TOML 表\"));\n    }\n}","typeGuard":null,"tryCatchPattern":"match upsert_context_entry_in_common_config(kind, id, body, config) {\n    Err(e) if e.to_string().ends_with(\"必须是 TOML 表\") => repair_or_rename_section(kind)?,\n    other => other?,\n}","preventionTips":["Never assign scalar/array values to reserved section names in config.toml","Run a pre-flight TOML schema check on the common config","Back up config.toml before hand edits"],"tags":["toml","config","type-mismatch"],"backgroundTag":"config-type-mismatch","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}