Lightning-AI/pytorch-lightning · error · TypeError
Expected a method or a string, but got: {type(method).__name
Error message
Expected a method or a string, but got: {type(method).__name__} What it means
FabricModule.mark_forward_method() only accepts a bound method or a method name string so it can register a user-defined method to be routed through the strategy wrapper (e.g. DDP sync). Passing any other type raises TypeError.
Source
Thrown at src/lightning/fabric/wrappers.py:168
def state_dict(
self, destination: Optional[T_destination] = None, prefix: str = "", keep_vars: bool = False
) -> Optional[dict[str, Any]]:
return self._original_module.state_dict(
destination=destination, # type: ignore[type-var]
prefix=prefix,
keep_vars=keep_vars,
)
@override
def load_state_dict( # type: ignore[override]
self, state_dict: Mapping[str, Any], strict: bool = True, **kwargs: Any
) -> _IncompatibleKeys:
return self._original_module.load_state_dict(state_dict=state_dict, strict=strict, **kwargs)
def mark_forward_method(self, method: Union[MethodType, str]) -> None:
"""Mark a method as a 'forward' method to prevent it bypassing the strategy wrapper (e.g., DDP)."""
if not isinstance(method, (MethodType, str)):
raise TypeError(f"Expected a method or a string, but got: {type(method).__name__}")
name = method if isinstance(method, str) else method.__name__
if name == "forward":
raise ValueError("You cannot mark the forward method itself as a forward method.")
if not isinstance(getattr(self._original_module, name, None), MethodType):
raise AttributeError(
f"You marked '{name}' as a forward method, but `{type(self._original_module).__name__}.{name}` does not"
f" exist or is not a method."
)
self._forward_methods.add(name)
def _redirection_through_forward(self, method_name: str) -> Callable:
assert method_name != "forward"
original_forward = self._original_module.forward
def wrapped_forward(*args: Any, **kwargs: Any) -> Any:
# Unpatch ourselves immediately before calling the method `method_name`
# because itself may want to call the real `forward`
self._original_module.forward = original_forwardView on GitHub (pinned to 9fed5c27d2)
Solutions
- Pass the method name as a string: fabric_module.mark_forward_method('generate')
- Or pass the bound method retrieved from the wrapped module instance itself, not from the class
- Unwrap partials/callables and pass the underlying method name instead
Example fix
# before
fabric_module.mark_forward_method(MyModel.generate)
fabric_module.mark_forward_method(functools.partial(m.generate, temperature=0.7))
# after
fabric_module.mark_forward_method('generate') Defensive patterns
Strategy: type-guard
Validate before calling
name = method if isinstance(method, str) else getattr(method, '__name__', None) assert name and callable(getattr(model, name, None)), 'pass a method name string instead'
Type guard
from types import MethodType
from typing import Union
def as_method_name(m: Union[MethodType, str]) -> str:
if isinstance(m, str):
return m
if isinstance(m, MethodType):
return m.__name__
raise TypeError(f'Expected MethodType or str, got {type(m).__name__}') Prevention
- Prefer passing the method name as a plain string
- Retrieve methods from the instance, not the class
When it happens
Trigger: Calling fabric_module.mark_forward_method(...) with something that is not a MethodType or str, e.g. passing the unbound class attribute (Model.generate, a plain function), a functools.partial, a property, or the return value of calling the method (model.generate()).
Common situations: Passing Model.generate instead of the bound instance method; wrapping the method in partial() to bake in kwargs; passing a lambda or a callable object; getting the attribute from a compiled/OptimizedModule wrapper.
Understand the failure class
Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.
Related errors
- Expected a precision plugin, got {plugin}
- `devices` selected with `CPUAccelerator` should be an int >
- `setup_optimizers` requires at least one optimizer as input.
- An optimizer should be passed only once to the `setup_optimi
- The optimizer has references to the model's meta-device para
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/d7be99e72ebd8669.
Report an issue: GitHub.