{"record":{"id":"48ba7faf4af263d9","repo":"databendlabs/databend","slug":"internal-error-entered-unreachable-code-48ba7f","errorCode":null,"errorMessage":"internal error: entered unreachable code","messagePattern":"internal error: entered unreachable code","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/service/src/interpreters/access/privilege_access.rs","lineNumber":319,"sourceCode":"                        if current_role.name == BUILTIN_ROLE_ACCOUNT_ADMIN {\n                            Ok(())\n                        } else {\n                            Err(ErrorCode::PermissionDenied(format!(\n                                \"Permission Denied: Operation '{:?}' on stage {sensitive_system_stage} is not allowed\",\n                                privilege\n                            )))\n                        }\n                    } else {\n                        Err(ErrorCode::PermissionDenied(format!(\n                            \"Permission Denied: Operation '{:?}' on stage {sensitive_system_stage} is not allowed\",\n                            privilege\n                        )))\n                    }\n                } else {\n                    Ok(())\n                };\n            }\n            _ => unreachable!(),\n        }\n\n        Ok(())\n    }\n\n    async fn get_role_names_and_ownerships(\n        &self,\n        tenant: &Tenant,\n    ) -> Result<(Vec<String>, Vec<SeqV<OwnershipInfo>>)> {\n        let roles = self.ctx.get_all_effective_roles().await?;\n        let roles_name = roles\n            .iter()\n            .map(|role| role.name.to_string())\n            .collect::<Vec<_>>();\n\n        if roles_name\n            .iter()\n            .any(|role_name| role_name == BUILTIN_ROLE_ACCOUNT_ADMIN)","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/service/src/interpreters/access/privilege_access.rs#L301-L337","documentation":"access_system_history (src/query/service/src/interpreters/access/privilege_access.rs:319) matches on the (catalog_name, db_name, stage_name) tuple and only handles two shapes: (Some, Some, None) for the sensitive history database and (None, None, Some) for the sensitive history stage. Any other combination — including all-None or mixed Some/Some/Some — falls into `_ => unreachable!()`, panicking the query node with 'internal error: entered unreachable code'.","triggerScenarios":"Any privilege validation call that reaches access_system_history with an argument shape outside the two handled patterns: e.g. validating access with both db_name and stage_name set, with catalog only (db_name None), or with all three None. Reached through validate_db_access, validate_table_access, validate_table_index_access, validate_drop_table_index_access, or validate_stage_access.","commonSituations":"A user queries or mutates a history/log table or stage through a code path that passes an unexpected combination of object identifiers (e.g. a fully-qualified name including both database and stage, or a validation hook invoked with None identifiers); common after upgrades where new object kinds route through the shared validation entry points.","solutions":["Identify which statement triggered validation with the unhandled identifier combination (check query log) and rework the statement to reference either a history database table or the history stage, not both/neither","Upgrade to a Databend version where access_system_history returns PermissionDenied for unhandled shapes instead of panicking","As a code fix, replace the `_ => unreachable!()` arm with `Err(ErrorCode::PermissionDenied(...))` or `Ok(())` so unexpected shapes degrade gracefully","File a bug with the exact SQL statement and Databend version"],"exampleFix":"// before\n_ => unreachable!(),\n// after\n_ => Err(ErrorCode::PermissionDenied(\n    \"Permission Denied: unhandled object shape for sensitive system history resource\".to_string(),\n)),","handlingStrategy":"validation","validationCode":"-- only reference history objects in the supported shapes:\n--   a table under <catalog>.system_history, or the history stage alone\nSELECT * FROM default.system_history.log_tbl;\n-- avoid mixed references like a db+stage in one grant","typeGuard":"let shape = (catalog_name.is_some(), db_name.is_some(), stage_name.is_some());\nif !matches!(shape, (true, true, false) | (false, false, true)) {\n    // route away from access_system_history\n}","tryCatchPattern":"// callers (validate_*_access) should pre-check identifier arity\nif (catalog.is_some() || db.is_some()) && stage.is_some() {\n    return Err(ErrorCode::BadArguments(\"cannot mix database and stage identifiers\".into()));\n}","preventionTips":["Grant privileges on history tables and stages with fully qualified, single-object references","Do not mix stage and database identifiers in one privilege operation","Keep account_admin role for sensitive history stage operations","Upgrade before using new system-history features on older nodes"],"tags":["rust","unreachable-panic","privilege","access-control"],"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"}