{"record":{"id":"2a43f5a833e53f15","repo":"databendlabs/databend","slug":"create-procedure-createorreplace-should-never-con","errorCode":null,"errorMessage":"create_procedure: CreateOrReplace should never conflict with existent","messagePattern":"create_procedure: CreateOrReplace should never conflict with existent","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/service/src/interpreters/interpreter_procedure_create.rs","lineNumber":95,"sourceCode":"                        .grant_ownership(\n                            &OwnershipObject::Procedure {\n                                procedure_id: reply.procedure_id,\n                            },\n                            &current_role.name,\n                        )\n                        .await?;\n                    RoleCacheManager::instance().invalidate_cache(&tenant);\n                }\n                Ok(PipelineBuildResult::create())\n            }\n            Err(_exist_error) => match self.plan.create_option {\n                CreateOption::Create => Err(ErrorCode::ProcedureAlreadyExists(format!(\n                    \"Procedure '{}' already exists\",\n                    self.plan.name.procedure_name()\n                ))),\n                CreateOption::CreateIfNotExists => Ok(PipelineBuildResult::create()),\n                CreateOption::CreateOrReplace => {\n                    unreachable!(\n                        \"create_procedure: CreateOrReplace should never conflict with existent\"\n                    );\n                }\n            },\n        }\n    }\n}\n","sourceCodeStart":77,"sourceCodeEnd":103,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/service/src/interpreters/interpreter_procedure_create.rs#L77-L103","documentation":"The create_procedure interpreter handles 'procedure already exists' conflicts only for plain CREATE. CREATE OR REPLACE is supposed to be resolved earlier by dropping and recreating the procedure, so if the conflict check is ever reached with a CreateOrReplace option the code panics via unreachable!, treating it as an impossible state.","triggerScenarios":"Calling CREATE OR REPLACE PROCEDURE where the early replace path did not take effect and the interpreter still falls into the 'already exists' conflict branch with CreateOption::CreateOrReplace.","commonSituations":"A regression in the pre-conflict resolution logic for CREATE OR REPLACE PROCEDURE; concurrent create/replace racing so both hit the existence-check branch.","solutions":["Verify the CREATE OR REPLACE pre-check/drop path runs before the conflict match; fix the control flow if it is skipped.","Check for concurrent procedure DDL on the same procedure name and add locking/serialization.","As a user workaround, use CREATE PROCEDURE IF NOT EXISTS or explicitly DROP PROCEDURE before CREATE."],"exampleFix":"// before\nCreateOption::CreateOrReplace => {\n    unreachable!(\"create_procedure: CreateOrReplace should never conflict with existent\");\n}\n// after\nCreateOption::CreateOrReplace => {\n    // replace path failed to pre-drop; fall back to dropping now\n    self.drop_if_exists().await?;\n    self.create_new().await\n}","handlingStrategy":"validation","validationCode":"-- Avoid relying on OR REPLACE conflict paths: check existence first\nSHOW PROCEDURES LIKE 'my_proc';\n-- or use IF NOT EXISTS\nCREATE PROCEDURE IF NOT EXISTS my_proc() ...;","typeGuard":null,"tryCatchPattern":"match res {\n    Err(e) if e.message().contains(\"CreateOrReplace should never conflict\") => {\n        // internal regression: fall back to DROP + CREATE\n    }\n    other => other?,\n}","preventionTips":["Serialize concurrent DDL on the same procedure name","Test CREATE OR REPLACE PROCEDURE against existing procedures in CI","Use DROP + CREATE explicitly instead of OR REPLACE if it misbehaves"],"tags":["rust","unreachable","procedure"],"backgroundTag":"internal-invariant-violation","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}