pydantic/monty · error

class member '{member_name}' missing from class-body locals

Error message

class member '{member_name}' missing from class-body locals

What it means

After preparing a class body, every declared class member must exist in the class-body scope's local slot map. If a member's name has no slot, class preparation panics — the members pass and the locals pass disagree about what the class body defines. It is an internal compiler invariant, not a user-facing error.

Source

Thrown at crates/monty/src/prepare.rs:1807

        };
        let FunctionState {
            locals: inner_locals,
            free_var_map: inner_free_var_map,
            cell_var_map: inner_cell_var_map,
            ..
        } = *inner_state;
        let namespace_size = inner_locals.len();
        drop(inner_prepare);

        // Resolve each member to its class-body-local slot. Every member is
        // assigned in the class body (a method `def` or a class-var `Assign`),
        // so it is always present as a plain local.
        let members = members
            .into_iter()
            .map(|member| {
                let slot = inner_locals.get(member.name_id).unwrap_or_else(|| {
                    let member_name = self.interner.get_str(member.name_id);
                    panic!("class member '{member_name}' missing from class-body locals")
                });
                Identifier::new_with_scope(member.name_id, member.position, slot, NameScope::Local)
            })
            .collect::<Vec<_>>();

        // Same-name collision (a known divergence — see `limitations/classes.md`):
        // a class-body owned cell means a method captured a class-body local that
        // ALSO has the same name as a variable in an enclosing scope. CPython keeps
        // these distinct (class-dict entry vs. closure cell); Monty maps one name
        // to a single slot, so it cannot represent both. Reject cleanly rather than
        // miscompile (the alternative is a runtime "expected cell reference" crash).
        if let Some(&name_id) = inner_cell_var_map.keys().next() {
            let name_str = self.interner.get_str(name_id);
            return Err(ParseError::not_implemented(
                format!(
                    "class member '{name_str}' that shadows a captured variable of the same name from an enclosing scope"
                ),
                position,

View on GitHub (pinned to adc986b362)

Solutions

  1. Fix member collection so it only reports names the class-body locals pass registers.
  2. Ensure the class-body scope analysis runs before members are mapped to slots.
  3. Reduce the failing class definition and compare slot registration against member enumeration.

Example fix

// before
let slot = inner_locals.get(member.name_id).unwrap_or_else(|| panic!("class member missing"));
// after
// ensure member enumeration uses the same pass that fills inner_locals
let members = collect_class_members(&body); // shared source of truth
let slot = inner_locals.get(member.name_id).unwrap_or_else(|| panic!("class member '{member_name}' missing from class-body locals"));
Defensive patterns

Strategy: validation

Validate before calling

// derive members and locals from the same AST pass
let members = collect_class_members(&body);
for m in &members { assert!(inner_locals.contains_key(m.name_id)); }

Prevention

When it happens

Trigger: Compiling a class whose members list (from AST analysis) contains a name the class-body scope never registered as a local — e.g. names introduced by exotic statements inside the class body, or a mismatch introduced by changes to member collection.

Common situations: Contributors modifying class-body preparation or member enumeration; Python test code with unusual class bodies (del statements, conditional defs, walrus in class scope).

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 pydantic/monty@adc986b362 (2026-09-13). Data as JSON: /api/errors/b568b5e8ed667c88. Report an issue: GitHub.