{"record":{"id":"38cdd8becd7a2c47","repo":"loco-rs/loco","slug":"create-db-schema","errorCode":null,"errorMessage":"create DB schema","messagePattern":"create DB schema","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/testing/db.rs","lineNumber":127,"sourceCode":"    }\n}\n\nimpl TestSupport for PostgresTest {\n    fn get_connection_str(&self) -> &str {\n        &self.connection_string\n    }\n\n    fn init_db<'a>(&'a self) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {\n        Box::pin(async move {\n            let pool = Pool::<Postgres>::connect(&self.root_connection_string)\n                .await\n                .expect(\"db connection should success\");\n            let query = format!(\"CREATE DATABASE {};\", self.schema_name);\n\n            sqlx::query(AssertSqlSafe(query))\n                .execute(&pool)\n                .await\n                .expect(\"create DB schema\");\n        })\n    }\n\n    fn cleanup_db(&self) {\n        let connection_string = self.root_connection_string.clone();\n        let table_name = self.schema_name.clone();\n\n        // Run the drop on a dedicated OS thread with its own runtime (not\n        // `tokio::task::spawn_blocking`, which schedules onto the ambient\n        // runtime and cannot be awaited from a sync/Drop context) and `.join()`\n        // it so cleanup fully completes before `cleanup_db` returns. This is\n        // safe to call from `Drop::drop` since nothing here is `.await`ed on\n        // the caller's runtime.\n        std::thread::spawn(move || {\n            let rt = tokio::runtime::Runtime::new().expect(\"create cleanup runtime\");\n\n            rt.block_on(async {\n                let pool = Pool::<Postgres>::connect(&connection_string)","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/loco-rs/loco/blob/23639d1e360dbc618073642b507d6f8664adbaff/src/testing/db.rs#L109-L145","documentation":"After connecting as root, `init_db` issues `CREATE DATABASE {schema_name};`. If that SQL fails — the database already exists, insufficient privileges, invalid identifier, or the server rejects concurrent creation — `.expect(\"create DB schema\")` panics inside the test-support initializer.","triggerScenarios":"Running tests with parallel test binaries that pick the same schema name (database already exists), a root user lacking CREATEDB, or a schema name with characters requiring quoting.","commonSituations":"Two test crates sharing the same `--test-threads` DB name in one CI job; leftover DB from a previous crashed run; managed Postgres (e.g. RDS/Cloud SQL) where the test user is not a superuser and cannot CREATE DATABASE.","solutions":["Re-run with a clean DB state or drop leftovers: `psql -U postgres -c 'DROP DATABASE IF EXISTS loco_test_x;'`","Ensure each test process/worker uses a unique schema name (unique suffix per PID) to avoid parallel collisions","Grant the test root CREATEDB: `ALTER USER test_user CREATEDB;` or run tests against a local superuser Postgres","Use `createdb`-capable local Postgres in CI rather than managed instances with restricted privileges"],"exampleFix":"// before\n$ cargo test  # panics: database \"loco_test_abc\" already exists\n// after\n$ psql -U postgres -c 'DROP DATABASE IF EXISTS loco_test_abc;'\n$ cargo test","handlingStrategy":"validation","validationCode":"// Ensure the user can create databases and no leftover DB exists\n// psql -U postgres -c \"SELECT rolcreatedb FROM pg_roles WHERE rolname='test_user';\"\n// psql -U postgres -c \"DROP DATABASE IF EXISTS loco_test_tmp;\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use unique per-process schema names to avoid parallel-test collisions","Drop leftover test databases before reruns","Grant CREATEDB to the test user","Avoid managed Postgres without CREATE DATABASE rights for integration tests"],"tags":["rust","postgres","database","testing","sql"],"backgroundTag":"database-query-failed","analyzedSha":"23639d1e360dbc618073642b507d6f8664adbaff","analyzedAt":"2026-09-12T01:47:20.769Z","contentChangedAt":"2026-09-12T01:47:20.769Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}