BigPizzaV3/CodexPlusPlus · error
model_metadata 必须是 JSON 对象
Error message
model_metadata 必须是 JSON 对象
What it means
After parsing model_metadata, the function requires the top-level JSON value to be an object (as_object). Arrays, strings, numbers or null produce "model_metadata 必须是 JSON 对象". Each object value must itself be an object (checked on the next lines) since it holds per-model metadata.
Solutions
- Wrap entries in a top-level object keyed by model slug: {"slug": {...}}.
- If you have an array, convert it to an object keyed by each record's slug field.
- Validate the parsed value is an object before assigning to the profile.
- Clear the field if metadata overrides are not needed.
Example fix
// before
model_metadata = "[{\"slug\": \"deepseek-v4-pro\", \"context_window\": 1000000}]"
// after
model_metadata = "{\"deepseek-v4-pro\": {\"context_window\": 1000000}}" Defensive patterns
Strategy: type-guard
Validate before calling
fn metadata_is_object(json: &str) -> bool {
serde_json::from_str::<serde_json::Value>(json)
.map(|v| v.is_object())
.unwrap_or(false)
} Type guard
fn is_object(v: &serde_json::Value) -> bool { v.is_object() } Try / catch
match apply_model_catalog_to_config(...) {
Err(e) if e.to_string().contains("model_metadata 必须是 JSON 对象") => {
// wrap array entries into a slug-keyed object and retry
}
other => other?,
} Prevention
- Always key metadata by model slug at the top level
- Reject arrays/scalars in form validation before saving
- Convert array-of-records inputs into slug-keyed objects in the UI layer
When it happens
Trigger: model_metadata set to a JSON array like [{...}], a bare string, or a number — valid JSON but not an object at top level.
Common situations: Users pasting an array of metadata records, or a single model's metadata object without the outer slug→object wrapper.
Related errors
- DreamSkin 社区主题元数据无效:
- 必须是 JSON 对象
- model_metadata JSON 解析失败:
- 整理结果父节点无效
- sidebar catalog entry is missing table
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/633d78c4139f5aeb.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/relay_config.rs:2144
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} 值必须是对象");
}
}
Ok(map.clone())
}
fn model_metadata_has_entries(
metadata: &serde_json::Map<String, Value>,
entry_slugs: &HashSet<String>,
) -> bool {
metadata.keys().any(|slug| entry_slugs.contains(slug))
}
fn apply_model_metadata_overrides(
catalog_json: &str,
override_map: &serde_json::Map<String, Value>,View on GitHub (pinned to b1ed92e5e4)