astral-sh/ruff · error

expected type alias

Error message

expected type alias

What it means

Scope::expect_type_alias unwraps as_type_alias(): it returns the StmtTypeAlias node only when the scope is a TypeAlias scope; any other scope kind panics with 'expected type alias'. It exists so callers like type_alias.rs can unwrap after establishing the scope kind.

Source

Thrown at crates/ty_python_core/src/scope.rs:446

        match self {
            Self::Function(function) => Some(function),
            _ => None,
        }
    }

    pub fn expect_function(&self) -> &AstNodeRef<ast::StmtFunctionDef> {
        self.as_function().expect("expected function")
    }

    fn as_type_alias(&self) -> Option<&AstNodeRef<ast::StmtTypeAlias>> {
        match self {
            Self::TypeAlias(type_alias) => Some(type_alias),
            _ => None,
        }
    }

    pub fn expect_type_alias(&self) -> &AstNodeRef<ast::StmtTypeAlias> {
        self.as_type_alias().expect("expected type alias")
    }

    /// Returns the anchor node index for this scope, or `None` for the module scope.
    ///
    /// This is used to compute relative node indices for expressions within the scope,
    /// providing a stable anchor that only changes when the scope-introducing node changes.
    pub fn node_index(&self) -> Option<NodeIndex> {
        match self {
            Self::Module => None,
            Self::Class(class) => Some(class.index()),
            Self::ClassTypeParameters(class) => Some(class.index()),
            Self::Function(function) => Some(function.index()),
            Self::FunctionTypeParameters(function) => Some(function.index()),
            Self::TypeAlias(type_alias) => Some(type_alias.index()),
            Self::TypeAliasTypeParameters(type_alias) => Some(type_alias.index()),
            Self::Lambda(lambda) => Some(lambda.index()),
            Self::ListComprehension(comp) => Some(comp.index()),
            Self::SetComprehension(comp) => Some(comp.index()),

View on GitHub (pinned to d1087a4b9e)

Solutions

  1. Use as_type_alias() and handle None instead of unwrapping
  2. Confirm the scope kind (match ScopeKind) before calling expect_type_alias
  3. If it fires inside ty on valid Python, capture a repro and file an issue

Example fix

// before
let alias_node = scope.node(db).expect_type_alias(); // panics if wrong kind

// after
let Some(alias_node) = scope.node(db).as_type_alias() else { return None; };
Defensive patterns

Strategy: type-guard

Validate before calling

if scope.kind() != ScopeKind::TypeAlias { return None; } // establish kind before unwrapping

Type guard

let is_type_alias_scope = |scope: &Scope| matches!(scope.kind(), ScopeKind::TypeAlias);

Try / catch

match scope.node().as_type_alias() { Some(alias) => { /* ... */ }, None => { /* wrong scope kind: skip or report */ } }

Prevention

When it happens

Trigger: Calling expect_type_alias on a scope that is not a TypeAlias scope - misuse of the API, or a code path that reaches a type-alias scope assumption for a scope created by another statement.

Common situations: Contributors adding type-alias-related semantic queries; refactors that change scope creation for `type X = ...` statements.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of astral-sh/ruff@d1087a4b9e (2026-08-20). Data as JSON: /api/errors/c55cc2648111f503. Report an issue: GitHub.