{"record":{"id":"7f7d01cee82f1a6d","repo":"risingwavelabs/risingwave","slug":"unexpected-referring-object-type","errorCode":null,"errorMessage":"unexpected referring object type: {}","messagePattern":"unexpected referring object type: (.+?)","errorType":"validation","errorClass":"MetaError","httpStatus":null,"severity":"error","filePath":"src/meta/src/controller/utils.rs","lineNumber":967,"sourceCode":"                }\n                ObjectType::Connection => {\n                    let connections: Vec<(String, String)> = Object::find()\n                        .join(JoinType::InnerJoin, object::Relation::Connection.def())\n                        .join(JoinType::InnerJoin, object::Relation::Database2.def())\n                        .join(JoinType::InnerJoin, object::Relation::Schema2.def())\n                        .select_only()\n                        .column(schema::Column::Name)\n                        .column(connection::Column::Name)\n                        .filter(object::Column::Oid.is_in(objs.iter().map(|o| o.oid)))\n                        .into_tuple()\n                        .all(db)\n                        .await?;\n                    details.extend(connections.into_iter().map(|(schema_name, view_name)| {\n                        format!(\"connection {}.{} depends on it\", schema_name, view_name)\n                    }));\n                }\n                // only the table, source, sink, subscription, view, connection and index will depend on other objects.\n                _ => bail!(\"unexpected referring object type: {}\", obj_type.as_str()),\n            }\n        }\n        if details.is_empty() {\n            return Ok(referring_objects);\n        }\n\n        return Err(MetaError::permission_denied(format!(\n            \"{} used by {} other objects. \\nDETAIL: {}\\n\\\n            {}\",\n            object_type.as_str(),\n            details.len(),\n            details.join(\"\\n\"),\n            match object_type {\n                ObjectType::Function | ObjectType::Connection | ObjectType::Secret =>\n                    \"HINT: DROP the dependent objects first.\",\n                ObjectType::Database | ObjectType::Schema => unreachable!(),\n                _ => \"HINT:  Use DROP ... CASCADE to drop the dependent objects too.\",\n            }","sourceCodeStart":949,"sourceCodeEnd":985,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/controller/utils.rs#L949-L985","documentation":"`validate_restrict_drop_and_collect_owned_objects` walks objects that refer to the object being dropped to enforce RESTRICT semantics. Only table, source, sink, subscription, view, connection and index are known to depend on other objects; if `drop_object` hands it any other object type, the function bails with \"unexpected referring object type: {}\". This is an internal exhaustiveness guard over the object-type dispatch.","triggerScenarios":"Calling `drop_object` (directly or via the metadata RPC) on an object type not in the handled set while it is used as a referring object — i.e. the match arms were not extended when a new object kind was added to the catalog.","commonSituations":"Development after adding a new catalog object type without updating the drop-validation match; internal tooling invoking drop validation with an unexpected `ObjectType`; version skew where a newer frontend/meta creates object kinds the current validation code does not know.","solutions":["Extend the match in `validate_restrict_drop_and_collect_owned_objects` with an arm for the new object type, collecting its referring objects like the existing arms.","If you are a user hitting this at runtime, upgrade meta and frontend to matching versions so both sides know the object type.","Check `obj_type.as_str()` in the message to identify the unhandled kind and confirm it is expected; if not, file/inspect how it got created.","As a workaround, drop the depending objects first manually so validation takes the supported path."],"exampleFix":"// before\n_ => bail!(\"unexpected referring object type: {}\", obj_type.as_str()),\n// after\nObjectType::Function => { /* collect referring objects for functions */ }\n_ => bail!(\"unexpected referring object type: {}\", obj_type.as_str()),","handlingStrategy":"validation","validationCode":"// Only drop object types the validation path supports\nconst SUPPORTED: &[ObjectType] = &[Table, Source, Sink, Subscription, View, Connection, Index];\nassert!(SUPPORTED.contains(&obj_type), \"unsupported referring type: {:?}\", obj_type);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When adding a new catalog object type, extend validate_restrict_drop_and_collect_owned_objects in the same PR","Keep meta and frontend versions in lockstep","Drop dependent objects explicitly before dropping exotic types"],"tags":["meta","drop","internal-invariant"],"backgroundTag":"unsupported-operation","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}