risingwavelabs/risingwave · error · MetaError

{0} named {1} already exists{under_creation}

Error message

{0} named {1} already exists{under_creation}

What it means

A DDL/create operation failed because an object of the given type with the given name already exists in the catalog. The optional third field is a JobId when the existing object is still being created, which appends " and is still being created" to the message.

Source

Thrown at src/meta/src/error.rs:83

    #[error("{0}")]
    PermissionDenied(String),

    #[error("Invalid worker: {0}, {1}")]
    InvalidWorker(WorkerId, String),

    #[error("Invalid parameter: {0}")]
    InvalidParameter(#[message] String),

    // Used for catalog errors.
    #[error("{0} id not found: {1}")]
    #[construct(skip)]
    CatalogIdNotFound(&'static str, String),

    #[error("table_fragment does not exist: id={0}")]
    FragmentNotFound(FragmentId),

    #[error("{0} named {1} already exists{under_creation}", under_creation = (.2).map(|_| " and is still being created").unwrap_or(""))]
    Duplicated(
        &'static str,
        String,
        // if under creation, take streaming job id, otherwise None
        Option<JobId>,
    ),

    #[error("Service unavailable: {0}")]
    Unavailable(#[message] String),

    #[error("Election failed: {0}")]
    Election(#[source] BoxedError),

    #[error("Cancelled: {0}")]
    Cancelled(String),

    #[error("System parameters error: {0}")]
    SystemParams(String),

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Use `CREATE ... IF NOT EXISTS` or check existence (`SHOW ...`) before creating.
  2. Drop the existing object first if it is unwanted (`DROP ...`).
  3. If the message says it is still being created, wait for the in-flight job to finish (monitor via `SHOW JOBS`) rather than retrying immediately.
  4. If a stale under-creation job is stuck, cancel it (`CANCEL JOBS`) and clean up before recreating.

Example fix

// before
CREATE MATERIALIZED VIEW mv_sales AS SELECT ...; -- Duplicated
// after
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_sales AS SELECT ...;
Defensive patterns

Strategy: validation

Validate before calling

let exists = catalog.has_object(kind, name).await?;
if !exists { create_object(kind, name).await?; }

Try / catch

match meta_result {
    Err(MetaError::Duplicated(kind, name, job)) if job.is_some() => { /* wait for in-flight creation */ }
    Err(MetaError::Duplicated(kind, name, _)) => { /* drop or use IF NOT EXISTS */ }
    other => other?,
}

Prevention

When it happens

Trigger: CREATE TABLE/MATERIALIZED VIEW/SOURCE/SINK/DATABASE/SCHEMA with a name that already exists; retried DDL after a partially completed create; creating a job while a same-named one is in CREATION state.

Common situations: Idempotency races from job frameworks re-submitting DDL, duplicate names in migration scripts, a previous create left under-creation state after failure or interruption.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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