PyO3/pyo3 · critical

failed to create type object for `{type_name}`

Error message

failed to create type object for `{type_name}`

What it means

type_object_init_failed is called from pyclass_type_object_raw when creating a #[pyclass]'s type object fails (e.g. during lazy type object initialization). It writes the underlying PyErr as unraisable and then panics, since the type object can never be produced.

Source

Thrown at src/impl_/pyclass/lazy_type_object.rs:260

) -> PyResult<()> {
    // We hold the GIL: the dictionary update can be considered atomic from
    // the POV of other threads.
    for (key, val) in items {
        crate::err::error_on_minusone(py, unsafe {
            ffi::PyObject_SetAttrString(type_object, key.as_ptr(), val.as_ptr())
        })?;
    }
    Ok(())
}

// This is necessary for making static `LazyTypeObject`s
unsafe impl<T> Sync for LazyTypeObject<T> {}

/// Used in the macro-expanded implementation of `type_object_raw` for `#[pyclass]` types
#[cold]
pub fn type_object_init_failed(py: Python<'_>, err: PyErr, type_name: &str) -> ! {
    err.write_unraisable(py, None);
    panic!("failed to create type object for `{type_name}`")
}

/// The full macro-expanded implementation of `type_object_raw` for `#[pyclass]` types, kept
/// out-of-line here to reduce the amount of macro-generated code.
#[inline]
pub fn pyclass_type_object_raw<T: PyClass>(py: Python<'_>) -> *mut ffi::PyTypeObject {
    use crate::types::PyTypeMethods;
    T::lazy_type_object()
        .get_or_try_init(py)
        .unwrap_or_else(|e| type_object_init_failed(py, e, <T as PyClass>::NAME))
        .as_type_ptr()
}

#[cold]
fn wrap_in_runtime_error(py: Python<'_>, err: PyErr, message: String) -> PyErr {
    let runtime_err = PyRuntimeError::new_err(message);
    runtime_err.set_cause(py, Some(err));
    runtime_err

View on GitHub (pinned to ac9b6899d3)

Solutions

  1. Inspect the unraisable PyErr printed to stderr just before the panic — it names the real cause
  2. Ensure the pyclass is registered/initialized in a healthy interpreter context (correct module init, not during finalization)
  3. Fix pyclass definition issues: conflicting names, invalid base classes, or misconfigured #[pyclass(...)] options
Defensive patterns

Strategy: try-catch

Validate before calling

// register classes only during module init, while the interpreter is healthy
#[pymodule]
fn mymod(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_class::<MyClass>()?;
    Ok(())
}

Try / catch

// capture the unraisable cause before the abort by installing a hook in tests
Python::with_gil(|py| unsafe {
    ffi::PyErr_SetInterrupt /* or run under a test harness that reads unraisable output */;
});

Prevention

When it happens

Trigger: First access to a #[pyclass] type object when PyType creation fails — usually because __new__/base class setup failed, module registration context is invalid, or the interpreter is in an error/initialization-failure state.

Common situations: Using a pyclass before/beyond a valid module init; interpreter shutdown while creating the type; invalid pyclass attributes (bad base, duplicate name) surfacing as PyErr at type creation.

Related errors


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