PyO3/pyo3 · error
Converting PyErr arguments failed: {}
Error message
Converting PyErr arguments failed: {} What it means
PyErr::arguments converts the exception's arguments into a Python object and is documented as infallible, but IntoPyObject can now fail. Since the signature can't return the error, pyo3 panics with the conversion error.
Source
Thrown at src/err/mod.rs:69
/// Represents the result of a Python call.
pub type PyResult<T> = Result<T, PyErr>;
/// Helper conversion trait that allows to use custom arguments for lazy exception construction.
pub trait PyErrArguments: Send + Sync {
/// Arguments for exception
fn arguments(self, py: Python<'_>) -> Py<PyAny>;
}
impl<T> PyErrArguments for T
where
T: for<'py> IntoPyObject<'py> + Send + Sync,
{
fn arguments(self, py: Python<'_>) -> Py<PyAny> {
// FIXME: `arguments` should become fallible
match self.into_pyobject(py) {
Ok(obj) => obj.into_any().unbind(),
Err(e) => panic!("Converting PyErr arguments failed: {}", e.into()),
}
}
}
impl PyErr {
/// Creates a new PyErr of type `T`.
///
/// `args` can be:
/// * a tuple: the exception instance will be created using the equivalent to the Python
/// expression `T(*tuple)`
/// * any other value: the exception instance will be created using the equivalent to the Python
/// expression `T(value)`
///
/// This exception instance will be initialized lazily. This avoids the need for the Python GIL
/// to be held, but requires `args` to be `Send` and `Sync`. If `args` is not `Send` or `Sync`,
/// consider using [`PyErr::from_value`] instead.
///
/// If `T` does not inherit from `BaseException`, then a `TypeError` will be returned.View on GitHub (pinned to ac9b6899d3)
Solutions
- Ensure the value passed to new_err has an infallible IntoPyObject impl (or convert to a supported type first, e.g. String)
- Provide your own error message instead of relying on arguments conversion
- Downcast/manually build the exception with .into_pyobject and handle the Err case yourself
Example fix
// before
PyValueError::new_err(my_custom_obj)
// after
PyValueError::new_err(format!("{}", my_custom_obj)) Defensive patterns
Strategy: validation
Validate before calling
fn args_are_trivially_convertible<T: for<'py> IntoPyObject<'py>>() -> bool { true } // prefer plain str/String/numbers as PyErr args Prevention
- Pass only infallibly-convertible types (String, i64, f64, &str) to new_err
- Format custom objects with Display before using them as exception args
- Test exception creation in debug mode to surface conversion failures early
When it happens
Trigger: Creating an exception whose args' IntoPyObject conversion fails (e.g. PyTypeError::new_err(value) where value's IntoPyObject impl returns Err, such as a type that can't be converted in the current interpreter configuration).
Common situations: new_err with a custom type whose IntoPyObject conversion errors at runtime; API evolution where arguments() was fallible-ized but callers kept the old infallible path.
Related errors
- attempted to fetch exception but none was set
- PyObject pointer is null
- Unknown Py_GIL_DISABLED value
- invalid hex encoding
- `pyo3_build_config::get()` requires a direct dependency on `
AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05).
Data as JSON: /api/errors/cfa074a7e094490a.
Report an issue: GitHub.