{"record":{"id":"515ff576740e53b2","repo":"risingwavelabs/risingwave","slug":"catalog-type-must-be-set","errorCode":null,"errorMessage":"`catalog.type` must be set","messagePattern":"`catalog\\.type` must be set","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/connector/src/connector_common/connection.rs","lineNumber":292,"sourceCode":"                bail!(\"`catalog.type` must not be set when `hosted_catalog` is set\");\n            }\n            if common.catalog_uri.is_some() {\n                bail!(\"`catalog.uri` must not be set when `hosted_catalog` is set\");\n            }\n            if common.catalog_name.is_some() {\n                bail!(\"`catalog.name` must not be set when `hosted_catalog` is set\");\n            }\n            if self.jdbc_user.is_some() {\n                bail!(\"`catalog.jdbc.user` must not be set when `hosted_catalog` is set\");\n            }\n            if self.jdbc_password.is_some() {\n                bail!(\"`catalog.jdbc.password` must not be set when `hosted_catalog` is set\");\n            }\n            return Ok(());\n        }\n\n        if common.catalog_type.is_none() {\n            bail!(\"`catalog.type` must be set\");\n        }\n\n        // Test catalog\n        let iceberg_common = common.clone();\n\n        let mut java_map = HashMap::new();\n        if let Some(jdbc_user) = &self.jdbc_user {\n            java_map.insert(\"jdbc.user\".to_owned(), jdbc_user.to_owned());\n        }\n        if let Some(jdbc_password) = &self.jdbc_password {\n            java_map.insert(\"jdbc.password\".to_owned(), jdbc_password.to_owned());\n        }\n        let catalog = iceberg_common\n            .resolve_catalog_config(java_map)?\n            .create_catalog()\n            .await?;\n        // test catalog by `table_exists` api\n        let test_table_ident = IcebergTableIdentifier {","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/connector_common/connection.rs#L274-L310","documentation":"RisingWave's Iceberg connector validates an external catalog configuration in `validate_connection`. When the config does not use `hosted_catalog`, the `catalog.type` field must be set so the connector knows which catalog backend (e.g. glue, rest, jdbc) to use. The library bails out with this error because a catalog connection cannot be created or tested without it.","triggerScenarios":"Calling CREATE CONNECTION / CREATE SINK / CREATE TABLE with an Iceberg catalog config that omits `catalog.type` while also not setting `hosted_catalog`.","commonSituations":"Users writing Iceberg connection SQL from scratch and forgetting the `catalog.type` key; copying examples that only show hosted catalog setups; typos like `catalog_type` instead of `catalog.type`.","solutions":["Add `catalog.type = '<backend>'` to the connection properties (e.g. 'rest', 'glue', 'jdbc').","If you intended RisingWave to host the catalog, set `hosted_catalog` instead.","Double-check property spelling: the key must be exactly `catalog.type` in the WITH clause."],"exampleFix":"// before\nCREATE CONNECTION iceberg_conn WITH (type = 'iceberg', catalog.uri = 'https://glue...');\n// after\nCREATE CONNECTION iceberg_conn WITH (type = 'iceberg', catalog.type = 'glue', catalog.uri = 'https://glue...');","handlingStrategy":"validation","validationCode":"// Validate Iceberg connection props before issuing CREATE CONNECTION\nfn validate_iceberg_props(props: &serde_json::Value) -> Result<(), String> {\n    let obj = props.as_object().ok_or(\"props must be an object\")?;\n    if !obj.contains_key(\"hosted_catalog\") && obj.get(\"catalog.type\").and_then(|v| v.as_str()).map_or(true, str::is_empty) {\n        return Err(\"`catalog.type` must be set when hosted_catalog is not used\".into());\n    }\n    Ok(())\n}","typeGuard":"fn has_catalog_type(props: &serde_json::Value) -> bool {\n    props.get(\"catalog.type\").and_then(|v| v.as_str()).map_or(false, |s| !s.is_empty())\n}","tryCatchPattern":null,"preventionTips":["Always include `catalog.type` in Iceberg WITH clauses unless using hosted_catalog.","Keep a checked-in SQL template for Iceberg connections and fill in placeholders.","Validate connection props in CI before deploying DDL."],"tags":["configuration","iceberg","catalog"],"backgroundTag":"missing-required-config-field","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"}