risingwavelabs/risingwave · error · ErrorCode
Duplicate Relation Name: {0}
Error message
Duplicate Relation Name: {0} What it means
RisingWave frontend's ErrorCode::DuplicateRelationName variant, rendered as "Duplicate Relation Name: {0}". It is raised by the binder when two relations in the same query scope share an implicit alias, e.g. self-joins without aliases or a subquery reusing an existing table alias (src/frontend/src/binder/bind_context.rs:273,294 and src/frontend/src/binder/query.rs:383).
Source
Thrown at src/frontend/src/error.rs:157
BoxedError,
),
#[error("Protocol error: {0}")]
ProtocolError(#[message] String),
#[error("Scheduler error: {0}")]
SchedulerError(
#[source]
#[backtrace]
BoxedError,
),
#[error("Task not found")]
TaskNotFound,
#[error("Session not found")]
SessionNotFound,
#[error("Invalid reference: {0}")]
InvalidReference(String),
#[error("Item not found: {0}")]
ItemNotFound(String),
#[error("Duplicate Relation Name: {0}")]
DuplicateRelationName(String),
#[error("Invalid insert operation: {0}")]
InsertViolation(String),
#[error("Invalid input syntax: {0}")]
InvalidInputSyntax(#[message] String),
#[error("Cannot compare in memory: {0}")]
MemComparableError(#[from] memcomparable::Error),
#[error("Error while de/se values: {0}")]
ValueEncodingError(
#[from]
#[backtrace]
ValueEncodingError,
),
#[error("Invalid value `{config_value}` for `{config_entry}`")]
InvalidConfigValue {
config_entry: String,
config_value: String,
},View on GitHub (pinned to 6469eb736d)
Solutions
- Give each duplicate relation a unique alias (FROM t AS t1, t AS t2).
- Rename the colliding subquery alias so it differs from existing relation names.
- Search the generated/ORM SQL for repeated AS names and make aliases unique.
- If scope is nested intentionally, ensure the duplicate lives in a different subquery scope, not the same FROM list.
Example fix
// before SELECT * FROM orders JOIN orders ON orders.id = orders.parent_id; // after SELECT * FROM orders o JOIN orders p ON o.id = p.parent_id;
Defensive patterns
Strategy: validation
Validate before calling
// lint SQL: every relation in a FROM list must have a unique alias assertUniqueAliases(fromClause);
Try / catch
try { await db.query(sql) } catch (e) {
if (/Duplicate Relation Name/.test(e.message)) { sql = aliasRelations(sql); retry(); }
else throw e;
} Prevention
- Always alias relations in self-joins.
- Enforce an SQL lint rule rejecting duplicate aliases in one FROM list.
- Use distinct, meaningful aliases for generated subqueries.
When it happens
Trigger: FROM t, t without aliases; joining a subquery whose derived alias collides with an existing relation name; aliasing a second relation with a name already bound in the same scope.
Common situations: Self-joins written without AS aliases; template-generated SQL that reuses default aliases; copy-pasted subqueries in large joins.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid reference: {0}
- Item not found: {0}
- Invalid insert operation: {0}
- {} must contain 1 argument
- Bind error: {0}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/7fb21dc09602d829.
Report an issue: GitHub.