{"record":{"id":"b17c427867c91fea","repo":"BigPizzaV3/CodexPlusPlus","slug":"unsupported-sidebar-catalog-table-table","errorCode":null,"errorMessage":"unsupported sidebar catalog table: {table}","messagePattern":"unsupported sidebar catalog table: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-data/src/provider_sync.rs","lineNumber":2709,"sourceCode":"    snapshot: &Value,\n) -> anyhow::Result<()> {\n    let thread_id = snapshot\n        .get(\"thread_id\")\n        .and_then(Value::as_str)\n        .filter(|id| !id.trim().is_empty())\n        .ok_or_else(|| anyhow::anyhow!(\"sidebar snapshot is missing thread_id\"))?;\n    if let Some(catalog) = snapshot.get(\"catalog\") {\n        let entries = catalog\n            .as_array()\n            .ok_or_else(|| anyhow::anyhow!(\"sidebar snapshot catalog must be an array\"))?;\n        let allowed_paths = sidebar_catalog_db_paths(codex_home)?;\n        for entry in entries {\n            let table = entry\n                .get(\"table\")\n                .and_then(Value::as_str)\n                .ok_or_else(|| anyhow::anyhow!(\"sidebar catalog entry is missing table\"))?;\n            if !SIDEBAR_CATALOG_TABLES.contains(&table) {\n                anyhow::bail!(\"unsupported sidebar catalog table: {table}\");\n            }\n            let path = entry\n                .get(\"db_path\")\n                .and_then(Value::as_str)\n                .map(PathBuf::from)\n                .ok_or_else(|| anyhow::anyhow!(\"sidebar catalog entry is missing db_path\"))?;\n            let canonical = fs::canonicalize(&path)?;\n            if !allowed_paths.contains(&canonical) {\n                anyhow::bail!(\"sidebar catalog database is not an allowed Codex database\");\n            }\n            let rows = entry\n                .get(\"rows\")\n                .and_then(Value::as_array)\n                .ok_or_else(|| anyhow::anyhow!(\"sidebar catalog entry rows must be an array\"))?;\n            for row in rows {\n                let row_id = row\n                    .get(\"thread_id\")\n                    .and_then(Value::as_str)","sourceCodeStart":2691,"sourceCodeEnd":2727,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-data/src/provider_sync.rs#L2691-L2727","documentation":"When restoring/validating the sidebar catalog from global state, each entry's 'table' field must be one of the whitelisted SIDEBAR_CATALOG_TABLES. This error is thrown for any entry naming a table outside that allowlist, preventing writes to arbitrary database tables.","triggerScenarios":"Restoring sidebar state whose catalog entry has a 'table' value not in SIDEBAR_CATALOG_TABLES — from a hand-edited .codex-global-state.json, a newer/older schema version, or corruption.","commonSituations":"User edited global state JSON manually; state file written by a different app version using renamed/extra tables; migration schema drift between versions.","solutions":["Fix the entry's 'table' field to one of the supported catalog table names (see SIDEBAR_CATALOG_TABLES in provider_sync.rs)","Remove the unsupported entry from the sidebar catalog section of .codex-global-state.json (or let a fresh sync rebuild it)","Align app versions: if the state was written by a newer version, restore the matching older state or upgrade this binary"],"exampleFix":"// before\n{\"table\": \"threads_extra\", \"db_path\": \"...\", \"rows\": []}\n// after\n{\"table\": \"threads\", \"db_path\": \"...\", \"rows\": []}","handlingStrategy":"validation","validationCode":"const TABLES: &[&str] = &[\"threads\"]; // mirror SIDEBAR_CATALOG_TABLES\nfn entry_table_ok(entry: &serde_json::Value) -> bool {\n    entry.get(\"table\").and_then(Value::as_str).map(|t| TABLES.contains(&t)).unwrap_or(false)\n}","typeGuard":"fn as_known_table(v: &Value) -> Option<&str> {\n    v.get(\"table\").and_then(Value::as_str).filter(|t| SIDEBAR_CATALOG_TABLES.contains(t))\n}","tryCatchPattern":"if let Err(e) = restore(&state) {\n    if e.to_string().starts_with(\"unsupported sidebar catalog table\") {\n        // drop/repair the offending entry and retry\n    }\n}","preventionTips":["Never hand-edit .codex-global-state.json; use app-managed sync","Keep the writer and reader app versions aligned","Validate table names against SIDEBAR_CATALOG_TABLES before persisting entries"],"tags":["validation","schema","whitelist"],"backgroundTag":"schema-validation-failed","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"}