PyO3/pyo3 · error

The 'weakref' weak reference instance should be valid (non-n

Error message

The 'weakref' weak reference instance should be valid (non-null and actually a weakref reference)

What it means

Guard panic in the PyWeakrefMethods::upgrade implementation for Bound<PyWeakref>. It fires only when PyWeakref_GetRef returns a negative status, i.e. the stored pointer is not actually a weakref.reference instance (or is invalid) — a broken type invariant that PyO3's safe wrappers assume can never happen, since the Bound<'py, PyWeakref> type guarantees a non-null genuine weakref.

Source

Thrown at src/types/weakref/anyref.rs:332

    /// })
    /// # }
    /// ```
    ///
    /// # Panics
    /// This function panics is the current object is invalid.
    /// If used properly this is never the case. (NonNull and actually a weakref type)
    ///
    /// [`PyWeakref_GetRef`]: https://docs.python.org/3/c-api/weakref.html#c.PyWeakref_GetRef
    /// [`weakref.ReferenceType`]: https://docs.python.org/3/library/weakref.html#weakref.ReferenceType
    /// [`weakref.ref`]: https://docs.python.org/3/library/weakref.html#weakref.ref
    fn upgrade(&self) -> Option<Bound<'py, PyAny>>;
}

impl<'py> PyWeakrefMethods<'py> for Bound<'py, PyWeakref> {
    fn upgrade(&self) -> Option<Bound<'py, PyAny>> {
        let mut obj: *mut ffi::PyObject = core::ptr::null_mut();
        match unsafe { ffi::compat::PyWeakref_GetRef(self.as_ptr(), &mut obj) } {
            core::ffi::c_int::MIN..=-1 => panic!("The 'weakref' weak reference instance should be valid (non-null and actually a weakref reference)"),
            0 => None,
            1..=core::ffi::c_int::MAX => Some(unsafe { obj.assume_owned_unchecked(self.py()) }),
        }
    }
}

#[cfg(test)]
mod tests {
    #[allow(unused_imports, reason = "conditionally used")]
    use crate::platform::prelude::*;
    use crate::types::any::{PyAny, PyAnyMethods};
    use crate::types::weakref::{PyWeakref, PyWeakrefMethods, PyWeakrefProxy, PyWeakrefReference};
    use crate::{Bound, PyResult, Python};

    fn new_reference<'py>(object: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyWeakref>> {
        let reference = PyWeakrefReference::new(object)?;
        reference.cast_into().map_err(Into::into)
    }

View on GitHub (pinned to ac9b6899d3)

Solutions

  1. Verify the value was obtained from PyWeakref::new / weakref.ref and not cast or from_object'd from an arbitrary Python object
  2. If interoperating with C or FFI, check the pointer with PyWeakref_Check before wrapping it in Bound<PyWeakref>
  3. Ensure the weakref object has not been created from a mismatched interpreter or already-invalidated runtime
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at src/types/weakref/anyref.rs:332 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05). Data as JSON: /api/errors/e2cb959a322f75e1. Report an issue: GitHub.