risingwavelabs/risingwave · error · anyhow::Error

mv not found

Error message

mv not found

What it means

get_table_catalog lists all state tables from meta and finds the one whose name equals mv_name. If no table matches, it returns this error wrapped in anyhow, so callers cannot resolve a TableCatalog for the requested name.

Source

Thrown at src/ctl/src/cmd_impl/table/scan.rs:38

use risingwave_pb::id::TableId;
use risingwave_rpc_client::MetaClient;
use risingwave_storage::StateStore;
use risingwave_storage::hummock::HummockStorage;
use risingwave_storage::monitor::MonitoredStateStore;
use risingwave_storage::store::PrefetchOptions;
use risingwave_storage::table::TableDistribution;
use risingwave_storage::table::batch_table::BatchTable;
use risingwave_stream::common::table::state_table::{StateTable, StateTableBuilder};

use crate::CtlContext;
use crate::common::HummockServiceOpts;

pub async fn get_table_catalog(meta: MetaClient, mv_name: String) -> Result<TableCatalog> {
    let mvs = meta.risectl_list_state_tables().await?;
    let mv = mvs
        .iter()
        .find(|x| x.name == mv_name)
        .ok_or_else(|| anyhow!("mv not found"))?
        .clone();
    Ok(TableCatalog::from(&mv))
}

pub async fn get_table_catalog_by_id(meta: MetaClient, table_id: TableId) -> Result<TableCatalog> {
    let mvs = meta.risectl_list_state_tables().await?;
    let mv = mvs
        .iter()
        .find(|x| x.id == table_id)
        .ok_or_else(|| anyhow!("mv not found"))?
        .clone();
    Ok(TableCatalog::from(&mv))
}

pub fn print_table_catalog(table: &TableCatalog) {
    println!("{:#?}", table);
}

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Run `risectl meta list-tables` (or equivalent) to see exact table names and correct the spelling
  2. Recreate the table/mv if it was dropped
  3. Use get_table_catalog_by_id with a valid table id if the name lookup keeps failing

Example fix

// before
scan(meta, "my_mv_typo".into(), ...)
// after
scan(meta, "my_mv".into(), ...)
Defensive patterns

Strategy: try-catch

Validate before calling

let names: Vec<_> = meta.risectl_list_state_tables().await?
    .into_iter().map(|t| t.name).collect();
if !names.contains(&mv_name) {
    return Err(anyhow!("table {} not found; available: {:?}", mv_name, names));
}

Try / catch

match get_table_catalog(meta.clone(), name.clone()).await {
    Ok(catalog) => { /* proceed */ }
    Err(e) if e.to_string().contains("mv not found") => {
        eprintln!("table '{}' not found; list tables first", name);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling scan/do_bench (or get_table_catalog directly) with a table name that does not exist in the cluster, is misspelled, or has been dropped.

Common situations: Typos in the mv/table name; table dropped between listing and lookup; using a materialized view name created after the risectl session's meta snapshot.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/73ebf3a95f742bc3. Report an issue: GitHub.