{"record":{"id":"58c6b9ffe73d45b0","repo":"astral-sh/ruff","slug":"expected-a-type-dynamic-variant","errorCode":null,"errorMessage":"Expected a Type::Dynamic variant","messagePattern":"Expected a Type::Dynamic variant","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ty_python_semantic/src/types.rs","lineNumber":2419,"sourceCode":"            Type::Intersection(intersection) => intersection\n                .positive(db)\n                .iter()\n                .any(|ty| ty.is_awaitable(db)),\n            _ => false,\n        }\n    }\n\n    /// Is a value of this type only usable in typing contexts?\n    pub fn is_type_check_only(&self, db: &'db dyn Db) -> bool {\n        match self {\n            Type::ClassLiteral(class_literal) => class_literal.type_check_only(db),\n            Type::FunctionLiteral(f) => {\n                f.has_known_decorator(db, FunctionDecorators::TYPE_CHECK_ONLY)\n            }\n            _ => false,\n        }\n    }\n\n    /// Returns whether this type is marked as deprecated via `@warnings.deprecated`.\n    pub fn is_deprecated(&self, db: &'db dyn Db) -> bool {\n        match self {\n            Type::FunctionLiteral(f) => f.implementation_deprecated(db).is_some(),\n            Type::Callable(callable) => callable.deprecated(db).is_some(),\n            Type::ClassLiteral(c) => c.deprecated(db).is_some(),\n            _ => false,\n        }\n    }\n\n    /// If the type is a specialized instance of the given `KnownClass`, returns the specialization.\n    fn known_specialization(\n        &self,\n        db: &'db dyn Db,\n        env: &ProgramEnvironment<'db>,\n        known_class: KnownClass,\n    ) -> Option<Specialization<'db>> {\n        let class_literal = known_class.try_to_class_literal(db, env)?;","sourceCodeStart":2401,"sourceCodeEnd":2437,"githubUrl":"https://github.com/astral-sh/ruff/blob/15f3fe6b15a5f00172f34b0f542f8ea277f5a586/crates/ty_python_semantic/src/types.rs#L2401-L2437","documentation":"Type::expect_dynamic is the unwrapping counterpart of as_dynamic: it asserts a Type value is the Dynamic variant (Any, Unknown, and friends). It fires when a code path that has already reasoned a type must be dynamic actually holds a different variant, i.e., the dynamic-approximation assumption upstream does not hold.","triggerScenarios":"Calling expect_dynamic on a Type that is not Dynamic - for example after a to_dynamic-style approximation or a match fallback that was expected to produce Any/Unknown but returned another variant, or after a new Type variant is added without updating dynamic-fallback logic.","commonSituations":"Contributor refactors that replace `if let Type::Dynamic` checks with expect_dynamic; addition of a new Type variant that should participate in dynamic approximations but does not.","solutions":["Capture the panic backtrace plus the expression being checked and file a ty issue with a minimal repro","As a contributor: prefer `let Type::Dynamic(d) = ty else { ... }` or as_dynamic() with an explicit non-dynamic fallback at the call site","Check whether a newly added Type variant needs handling in the dynamic-approximation helpers"],"exampleFix":"// before\nlet dynamic = ty.expect_dynamic();\n\n// after\nif let Some(dynamic) = ty.as_dynamic() {\n    // dynamic path\n} else {\n    // explicit non-dynamic path\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn is_dynamic<'db>(ty: Type<'db>) -> bool {\n    matches!(ty, Type::Dynamic(_))\n}","tryCatchPattern":null,"preventionTips":["Prefer as_dynamic()/`if let Type::Dynamic` over expect_dynamic at call sites that can receive other variants","When adding a Type variant, audit dynamic-approximation helpers and their expect_dynamic call sites","Cover the non-dynamic path in tests so the assumption is checked rather than assumed"],"tags":["rust","ty","types","enum","panic","variant-mismatch"],"backgroundTag":"enum-variant-expect-mismatch","analyzedSha":"15f3fe6b15a5f00172f34b0f542f8ea277f5a586","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}