sweep_orphans Schema-Drop Race
On this page
Overview
canopy_test_lib::db::sweep_orphans(base_url, prefix) issues DROP SCHEMA <name> CASCADE for every schema whose name matches LIKE '{prefix}%'. Called with a workspace-shared prefix (test_) from a test that runs alongside other tests using EphemeralSchema, it will drop a sibling test’s live schema mid-run. This runbook documents the hazard and the safe-usage rule.
Symptom
A test in another crate fails non-deterministically with either:
-
relation "<table>" does not exist(Postgres42P01) — its schema was dropped out from under it; or -
a wall-clock blowout ("took 10.78s — per-program timeout not isolating") — lock contention during the drop.
Observed 2026-05-25: services/canopy-eligibility/tests/orchestrator_dispatch_test.rs::slow_program_does_not_block_combined_result failed both ways.
Root cause
sweep_orphans runs each DROP SCHEMA inside a SET LOCAL lock_timeout = '500ms' transaction (since the #520/#521/#523 MR), so a schema held by an active query raises lock_timeout rather than blocking. But lock_timeout only helps when the foreign session is mid-query — an idle pooled connection whose search_path points at the schema holds no namespace-level lock, so DROP SCHEMA CASCADE succeeds against it immediately and its next query `42P01`s.
The trigger 2026-05-25: crates/canopy-test-lib/tests/db_cleanup_test.rs called sweep_orphans(&url) with the shared test_ prefix. nextest runs canopy-test-lib and canopy-eligibility as separate OS processes against the same devstack Postgres, so the cleanup test’s sweep clobbered the eligibility test’s live test_<uuid> schema.
Safe-usage rule
-
Production / xtask usage: only call
sweep_orphans(url, "test_")from a single-process context (e.g.cargo xtask dev refreshbefore/after the suite), never alongside parallel test binaries. -
Test fixtures: mint your own unique prefix and sweep only that:
let prefix = format!("sweepfixture_{}_", uuid_no_hyphens()); // create schemas under `prefix` via raw SQL ... sweep_orphans(&url, &prefix); // scoped — cannot touch another crate's test_<uuid>See
crates/canopy-test-lib/tests/db_cleanup_test.rs::sweep_orphans_drops_matching_schemas_and_is_idempotentfor the pattern.
Diagnosis pattern that worked
Five contextless agents dispatched in parallel without hypotheses: two converged on the sweep_orphans race (the true proximate cause); three chased the orchestrator’s retry policy and EphemeralSchema::Drop (real concerns, but not the proximate cause of these specific failures). The convergent answer is the trustworthy one.
Related
-
Dashboard E2E flake and Stale JWKS recovery — other devstack-level test flakes.
-
Developer Guide — nextest concurrency model + running tests.