{"record":{"id":"0223244c304dd2fa","repo":"clockworklabs/SpacetimeDB","slug":"unable-to-lock-database-for-initialization","errorCode":null,"errorMessage":"unable to lock database {} for initialization","messagePattern":"unable to lock database (.+?) for initialization","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/core/src/host/host_controller.rs","lineNumber":458,"sourceCode":"        &self,\n        database: Database,\n        replica_id: u64,\n    ) -> anyhow::Result<(watch::Receiver<ModuleHost>, Option<BootstrapCompletion>)> {\n        // Try a read lock first.\n        {\n            if let Ok(guard) = self.acquire_read_lock(replica_id).await\n                && let Some(host) = &*guard\n            {\n                trace!(\"cached host {}/{}\", database.database_identity, replica_id);\n                return Ok((host.module.subscribe(), None));\n            }\n        }\n\n        // We didn't find a running module, so take a write lock.\n        // Since [`tokio::sync::RwLock`] doesn't support upgrading of read locks,\n        // we'll need to check again if a module was added meanwhile.\n        let Ok(mut guard) = self.acquire_write_lock(replica_id).await else {\n            bail!(\n                \"unable to lock database {} for initialization\",\n                database.database_identity\n            );\n        };\n        if let Some(host) = &*guard {\n            trace!(\n                \"cached host {}/{} (lock upgrade)\",\n                database.database_identity,\n                replica_id\n            );\n            return Ok((host.module.subscribe(), None));\n        }\n\n        trace!(\"launch host {}/{}\", database.database_identity, replica_id);\n\n        // `HostController::clone` is fast,\n        // as all of its fields are either `Copy` or wrapped in `Arc`.\n        let this = self.clone();","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/fdd647dfac506d0967cc4492e9fce380706c94cb/crates/core/src/host/host_controller.rs#L440-L476","documentation":"try_init_host takes a per-replica write lock before creating or fetching the module host for a database. Lock acquisition is wrapped in a 5-second timeout (added to surface deadlocks during debugging); when the lock cannot be taken in time because another long-running operation is holding it, initialization fails with this error naming the database identity.","triggerScenarios":"A concurrent publish, update, or subscription workload holding the replica's host lock longer than 5 seconds (e.g. a reducer call or module task in flight, or a slow host initialization) while another request tries to initialize the same database; or a genuinely stuck/deadlocked holder that never releases.","commonSituations":"Two clients publishing or publishing+subscribing to the same database simultaneously; a previous operation hung; automated tooling retrying publishes in a tight loop against a busy replica.","solutions":["Wait for the in-flight operation on that database to finish, then retry the publish/init","Check server logs to identify what held the lock (the timeout exists specifically to expose holders/deadlocks)","If it persists and no operation is legitimately running, restart the spacetimedb process to clear stuck locks","Serialize publishes to the same database in your tooling (deploy queue, CI mutex)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"# shell: retry while a concurrent op holds the replica lock (5s timeout)\nfor i in 1 2 3; do\n  spacetime publish my-db --project-path . && exit 0\n  echo \"attempt $i: database lock busy - retrying\" >&2\n  sleep 10\ndone\nexit 1","preventionTips":["Serialize publishes to the same database (CI mutex / deploy queue)","Avoid publishing while heavy reducer traffic runs on the target database","Alert on repeated lock timeouts - they indicate a stuck holder or deadlock","Keep the server on a current version; the lock timeout exists to expose holder issues"],"tags":["concurrency","locks","publish","server","timeout"],"backgroundTag":"lock-acquisition-timeout","analyzedSha":"fdd647dfac506d0967cc4492e9fce380706c94cb","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}