astral-sh/ruff · error
The meta-type of an instance-like type should always have an
Error message
The meta-type of an instance-like type should always have an MRO
What it means
class_namespace_member looks a name up on the meta-type of a class; the expectation is that the meta-type of an instance-like type always has an MRO, so find_name_in_mro_with_policy must return Some. The expect fires when that MRO walk returns None for the class literal being used as the lookup anchor.
Source
Thrown at crates/ty_python_semantic/src/types.rs:3771
_ => Some(
class
.class_member(db, env, name, policy)
.map_type(|member| property_wrapper_descriptor(db, env, name, member)),
),
}
}
Type::GenericAlias(alias) if alias.is_typed_dict(db) => {
Some(alias.origin(db).typed_dict_member(
db,
env,
Some(alias.specialization(db)),
name,
policy,
))
}
Type::GenericAlias(alias) => Some(
ClassType::from(*alias)
.class_member(db, env, name, policy)
.map_type(|member| property_wrapper_descriptor(db, env, name, member)),
),
Type::SubclassOf(subclass_of_ty) => {
subclass_of_ty.find_name_in_mro_with_policy(db, env, name, policy)
}
// Note: `super(pivot, owner).__class__` is `builtins.super`, not the owner's class.
// `BoundSuper` should look up the name in the MRO of `builtins.super`.
Type::BoundSuper(_) => KnownClass::Super
.to_class_literal(db, env)
.find_name_in_mro_with_policy(db, env, name, policy),
// We eagerly normalize type[object], i.e. Type::SubclassOf(object) to `type`,
// i.e. Type::NominalInstance(type). So looking up a name in the MRO of
// `Type::NominalInstance(type)` is equivalent to looking up the name in theView on GitHub (pinned to 15f3fe6b15)
Solutions
- Reduce to the class plus attribute access that panics and file a ty issue
- Inspect the class's metaclass and base chain (cycles, missing bases in stubs) and fix the source or stub definitions
- As a contributor: return an undefined place instead of unwrapping when the MRO walk fails, so lookup degrades gracefully
Defensive patterns
Strategy: fallback
Try / catch
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| check_file(&db, file)));
match result {
Ok(diags) => diags,
Err(payload) => { log::warn!("ty panicked on member lookup in {}: {:?}", file, payload); vec![] }
} Prevention
- Keep stub files' class hierarchies acyclic and complete (every base resolvable)
- Regenerate rather than hand-edit stubs with metaclass bases
- Report the class plus attribute access if the hierarchy looks valid - the fix belongs in ty's MRO fallback
When it happens
Trigger: Instance/class member lookup where the metaclass's MRO cannot be produced: circular or malformed class hierarchies, stubs with missing bases, or class tables that are stale after incremental edits.
Common situations: Hand-edited or generated stub files with broken `__bases__` chains; exotic metaclasses; LSP incremental rechecks where class metadata changed mid-session.
Related errors
- `find_name_in_mro` should return `Some` for a class literal
- Calling `find_name_in_mro` on dynamic type should return `So
- Will return Some() when called on class literal
- Expected a Type::Dynamic variant
- matched `Type::Divergent` above
AI-assisted analysis of astral-sh/ruff@15f3fe6b15 (2026-08-20).
Data as JSON: /api/errors/102f2c12e2822278.
Report an issue: GitHub.