{"record":{"id":"1a3b7369205214f8","repo":"clockworklabs/SpacetimeDB","slug":"invalid-private-initialization-record","errorCode":null,"errorMessage":"invalid private initialization record","messagePattern":"invalid private initialization record","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/standalone/src/control_db/environment.rs","lineNumber":42,"sourceCode":"// Keep the existing tree name for on-disk compatibility.\nconst METADATA_TREE: &str = \"database_bootstrap\";\nconst VALUES_TREE: &str = \"initial_environment\";\n\n#[derive(serde::Serialize, serde::Deserialize)]\n#[serde(deny_unknown_fields)]\nstruct InitializationMetadata {\n    version: u8,\n    database_id: u64,\n    identity: Identity,\n    program: Hash,\n    generation: u64,\n    // Earlier ENV development builds did not record the replica ID.\n    #[serde(default)]\n    replica_id: Option<u64>,\n}\n\nfn invalid() -> Error {\n    Error::Other(anyhow::anyhow!(\"invalid private initialization record\"))\n}\n\nimpl InitializationMetadata {\n    fn decode(bytes: &[u8], database: &Database) -> Result<Self> {\n        if bytes.len() > 1024 {\n            return Err(invalid());\n        }\n        let value: Self = serde_json::from_slice(bytes).map_err(|_| invalid())?;\n        if value.version != 1\n            || value.database_id != database.id\n            || value.identity != database.database_identity\n            || value.generation == 0\n        {\n            return Err(invalid());\n        }\n        Ok(value)\n    }\n","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/standalone/src/control_db/environment.rs#L24-L60","documentation":"The standalone control DB stores per-database initialization (private environment) metadata as opaque bytes; decode() validates them (size <= 1024, decodeable shape, replica ID consistency with the Database row). Any mismatch yields this single Error::Other sentinel via invalid(), used by decode and every caller (current_generation, initial_environment, upsert_database_with_environment, delete_database_and_environment).","triggerScenarios":"Reading initialization metadata whose bytes exceed 1024 bytes, fail to deserialize into InitializationMetadata, or whose replica_id disagrees with the Database record; e.g. after a manual DB edit or a failed/aborted migration.","commonSituations":"Upgrading an older ENV development build that did not record replica_id (now tolerated via serde default, but other shape changes are not); corrupting control_db storage manually; restoring a backup partially.","solutions":["Recreate the database record: delete and re-publish the database so fresh initialization metadata is written.","Restore a consistent control_db backup that matches the current metadata format.","If upgrading from an early ENV build, run the proper migration rather than hand-editing the stored bytes."],"exampleFix":"// before: hand-crafted metadata bytes\nlet bytes = serde_json::to_vec(&json!({\"generation\": 3, \"env\": {...}}))?; // >1024B / wrong shape\n\n// after: write through the supported API\ncontrol_db.upsert_database_with_environment(&database, &environment, None)?;","handlingStrategy":"validation","validationCode":"// validate metadata bytes before use\nfn valid(bytes: &[u8]) -> bool { bytes.len() <= 1024 && serde_json::from_slice::<InitializationMetadata>(bytes).is_ok() }","typeGuard":"fn is_valid_meta(bytes: &[u8]) -> bool { bytes.len() <= 1024 && serde_json::from_slice::<InitializationMetadata>(bytes).is_ok() }","tryCatchPattern":"match InitializationMetadata::decode(&bytes, &db) { Err(_) => recreate_database_record(), Ok(m) => use(m) }","preventionTips":["Never hand-edit control_db metadata blobs","Use supported APIs to write environment metadata","Back up and restore control_db atomically"],"tags":["control-db","deserialization","environment","corruption"],"backgroundTag":"invalid-argument-format","analyzedSha":"eddf9f5014579a50d4b67630e28b6e15cad9c4af","analyzedAt":"2026-09-20T12:15:59.611Z","contentChangedAt":"2026-09-20T12:15:59.611Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}