BigPizzaV3/CodexPlusPlus · error
sidebar snapshot is missing thread_id
Error message
sidebar snapshot is missing thread_id
What it means
The sidebar snapshot restore path validates that a snapshot JSON contains a non-empty string thread_id before touching any catalog databases. If the field is absent, not a string, or blank, the restore is rejected with this error. It is a guard so row filtering in the catalog is always anchored to a valid thread identity.
Solutions
- Add a valid non-empty "thread_id" string field to the snapshot JSON at the top level
- Re-export the sidebar snapshot from the manager so the field is populated
- Validate the snapshot JSON schema before attempting restore (jq '.thread_id' snapshot.json)
- Check for version skew: confirm the snapshot was produced by the same CodexPlusPlus version
Example fix
// before
{ "catalog": [ ... ] }
// after
{ "thread_id": "3f9c...", "catalog": [ ... ] } Defensive patterns
Strategy: validation
Validate before calling
function hasThreadId(snapshot) {
return typeof snapshot?.thread_id === 'string' && snapshot.thread_id.trim() !== '';
}
if (!hasThreadId(snapshot)) throw new Error('snapshot has no usable thread_id'); Type guard
function isValidSnapshot(v) {
return typeof v === 'object' && v !== null &&
typeof v.thread_id === 'string' && v.thread_id.trim() !== '';
} Try / catch
try {
restore_sidebar_snapshot(&snapshot, codex_home)?;
} catch (e) {
if (String(e).includes('missing thread_id')) {
// reject/re-export the snapshot
reportInvalidSnapshot(snapshot);
}
} Prevention
- Validate snapshot JSON schema right after export
- Never hand-edit snapshots; always re-export
- Include thread_id in any custom export tooling
- Version-stamp snapshots and check compatibility before restore
When it happens
Trigger: Calling the sidebar snapshot restore function with a snapshot Value that lacks snapshot["thread_id"], has it as a non-string (e.g. number), or as an empty/whitespace-only string.
Common situations: Hand-edited or truncated snapshot JSON; a snapshot exported by an older/newer version with a renamed field; snapshot produced by a failed export that omitted thread_id; copying a partial snapshot file.
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 row is missing thread_id
- sidebar snapshot catalog must be an array
- 整理结果包含无效来源
- 缺少 command 或 url
- JSON 顶层必须是对象
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/ad29fa4460f622d6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-data/src/provider_sync.rs:2697
validate_thread_sidebar_snapshot(codex_home, snapshot)?;
let thread_id = snapshot
.get("thread_id")
.and_then(Value::as_str)
.unwrap_or_default();
let mut restored = restore_thread_to_global_state(codex_home, thread_id, snapshot)?;
restored += restore_thread_to_catalog_dbs(codex_home, thread_id, snapshot)?;
Ok(restored)
}
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"))?;View on GitHub (pinned to b1ed92e5e4)