BigPizzaV3/CodexPlusPlus · error
sidebar catalog entry is missing table
Error message
sidebar catalog entry is missing table
What it means
Each entry inside a sidebar snapshot's catalog array must identify which SQLite table it applies to via a string "table" field. If an entry lacks the field or it is not a string, restore aborts with this error. The table name is then checked against the allow-list SIDEBAR_CATALOG_TABLES.
Solutions
- Add "table": "<allowed-table-name>" to each catalog entry in the snapshot
- Use a table name present in SIDEBAR_CATALOG_TABLES (e.g. the threads catalog table)
- Re-export the snapshot from the app to get correctly shaped entries
- Rename wrong keys (e.g. "tableName" -> "table") in the snapshot JSON
Example fix
// before
{ "db_path": "...", "rows": [ ... ] }
// after
{ "table": "thread_catalog", "db_path": "...", "rows": [ ... ] } Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED_TABLES = SIDEBAR_CATALOG_TABLES; // keep in sync with Rust allow-list
for (const entry of snapshot.catalog ?? []) {
if (typeof entry?.table !== 'string' || !ALLOWED_TABLES.includes(entry.table)) {
throw new Error(`bad catalog table: ${entry?.table}`);
}
} Type guard
function entryHasTable(e) {
return typeof e === 'object' && e !== null && typeof e.table === 'string';
} Try / catch
try {
restore_sidebar_snapshot(&snapshot, codex_home)?;
} catch (e) {
if (String(e).includes('missing table')) {
reportEntryMissingField(snapshot, 'table');
}
} Prevention
- Always set "table" when constructing catalog entries
- Share a single constant/table-name enum between exporter and restorer
- Validate entries before writing snapshot files
- Avoid renaming the field across versions without a migration
When it happens
Trigger: A catalog array element without a "table" key (or with a non-string value) passed to the sidebar snapshot restore function.
Common situations: Hand-assembled snapshot missing per-entry metadata; schema drift between exporter versions (field renamed or moved); entries constructed programmatically with wrong keys (e.g. "tableName").
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- sidebar catalog entry rows must be an array
- sidebar catalog entry is missing db_path
- sidebar catalog row is missing thread_id
- sidebar snapshot catalog must be an array
- catalog JSON 解析失败:
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/188725761573e6da.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-data/src/provider_sync.rs:2707
pub fn validate_thread_sidebar_snapshot(
codex_home: &Path,
snapshot: &Value,
) -> anyhow::Result<()> {
let thread_id = snapshot
.get("thread_id")
.and_then(Value::as_str)
.filter(|id| !id.trim().is_empty())
.ok_or_else(|| anyhow::anyhow!("sidebar snapshot is missing thread_id"))?;
if let Some(catalog) = snapshot.get("catalog") {
let entries = catalog
.as_array()
.ok_or_else(|| anyhow::anyhow!("sidebar snapshot catalog must be an array"))?;
let allowed_paths = sidebar_catalog_db_paths(codex_home)?;
for entry in entries {
let table = entry
.get("table")
.and_then(Value::as_str)
.ok_or_else(|| anyhow::anyhow!("sidebar catalog entry is missing table"))?;
if !SIDEBAR_CATALOG_TABLES.contains(&table) {
anyhow::bail!("unsupported sidebar catalog table: {table}");
}
let path = entry
.get("db_path")
.and_then(Value::as_str)
.map(PathBuf::from)
.ok_or_else(|| anyhow::anyhow!("sidebar catalog entry is missing db_path"))?;
let canonical = fs::canonicalize(&path)?;
if !allowed_paths.contains(&canonical) {
anyhow::bail!("sidebar catalog database is not an allowed Codex database");
}
let rows = entry
.get("rows")
.and_then(Value::as_array)
.ok_or_else(|| anyhow::anyhow!("sidebar catalog entry rows must be an array"))?;
for row in rows {
let row_id = rowView on GitHub (pinned to b1ed92e5e4)