risingwavelabs/risingwave · error
table id {table_id} may have been dropped
Error message
table id {table_id} may have been dropped What it means
In snapshot batch query setup (`batch_query_epoch`, src/frontend/src/scheduler/snapshot.rs:181), each table id in the query is looked up in the snapshot's `state_table_info` to obtain its committed epoch. If a table id is missing from the mapping, the code assumes the table `may have been dropped` between query planning and snapshot epoch resolution, and returns this anyhow error (surfaced as `SchedulerError::Internal`).
Source
Thrown at src/frontend/src/scheduler/snapshot.rs:181
/// A reference to a frontend-pinned snapshot.
pub type PinnedSnapshotRef = Arc<PinnedSnapshot>;
impl PinnedSnapshot {
fn batch_query_epoch(
&self,
read_storage_tables: &HashSet<TableId>,
) -> Result<Epoch, SchedulerError> {
// use the min committed epoch of tables involved in the scan
let epoch = read_storage_tables
.iter()
.map(|table_id| {
self.value
.state_table_info
.info()
.get(table_id)
.map(|info| Epoch(info.committed_epoch))
.ok_or_else(|| anyhow!("table id {table_id} may have been dropped"))
})
.try_fold(None, |prev_min_committed_epoch, committed_epoch| {
committed_epoch.map(|committed_epoch| {
if let Some(prev_min_committed_epoch) = prev_min_committed_epoch
&& prev_min_committed_epoch <= committed_epoch
{
Some(prev_min_committed_epoch)
} else {
Some(committed_epoch)
}
})
})?
.unwrap_or_else(Epoch::now);
Ok(epoch)
}
pub fn version(&self) -> &FrontendHummockVersion {
&self.valueView on GitHub (pinned to 6469eb736d)
Solutions
- Re-run the query; if the object was intentionally dropped it should now fail with a clear not-found error instead.
- Verify the table/MV still exists (`SHOW MATERIALIZED VIEWS;` / `SHOW TABLES;`) and recreate it if it was dropped.
- Avoid dropping a table while queries against it are in flight; coordinate DDL and query workloads.
- If the table exists but the error persists, check meta consistency and re-create the object or restart the meta service.
Example fix
// before: SELECT * FROM mv; -- dropped concurrently // after CREATE MATERIALIZED VIEW IF NOT EXISTS mv AS SELECT ...; SELECT * FROM mv;
Defensive patterns
Strategy: retry
Validate before calling
-- Check the object still exists before querying SELECT 1 FROM rw_catalog.rw_tables WHERE table_id = <id>; SELECT 1 FROM rw_catalog.rw_materialized_views WHERE name = 'mv';
Try / catch
match scheduler_result {
Err(e) if e.to_string().contains("may have been dropped") => {
// transient DDL race: re-plan and retry once
retry_query_once();
}
r => r?,
} Prevention
- Avoid DROP TABLE/MV while queries against it run.
- Wrap queries on volatile objects in retry logic.
- Recreate objects before re-running dependent queries after DDL.
When it happens
Trigger: Running a batch query whose plan references a state table that is absent from the meta snapshot: the table (or its owning MV/index) was dropped concurrently after the query was planned.
Common situations: Race between `DROP TABLE`/`DROP MATERIALIZED VIEW` and a running SELECT against that object; stale cached plans referencing removed tables.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Pin snapshot error: {0} fails to get epoch {1}
- Iceberg metadata scan should not have input executors
- Chunk size can't be zero!
- Failed to execute time travel query
- Invalid datetime: {value} {unit} is out of range
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/63d132e7a3de20c9.
Report an issue: GitHub.