{"record":{"id":"d7be99e72ebd8669","repo":"Lightning-AI/pytorch-lightning","slug":"expected-a-method-or-a-string-but-got-type-meth","errorCode":null,"errorMessage":"Expected a method or a string, but got: {type(method).__name__}","messagePattern":"Expected a method or a string, but got: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/lightning/fabric/wrappers.py","lineNumber":168,"sourceCode":"    def state_dict(\n        self, destination: Optional[T_destination] = None, prefix: str = \"\", keep_vars: bool = False\n    ) -> Optional[dict[str, Any]]:\n        return self._original_module.state_dict(\n            destination=destination,  # type: ignore[type-var]\n            prefix=prefix,\n            keep_vars=keep_vars,\n        )\n\n    @override\n    def load_state_dict(  # type: ignore[override]\n        self, state_dict: Mapping[str, Any], strict: bool = True, **kwargs: Any\n    ) -> _IncompatibleKeys:\n        return self._original_module.load_state_dict(state_dict=state_dict, strict=strict, **kwargs)\n\n    def mark_forward_method(self, method: Union[MethodType, str]) -> None:\n        \"\"\"Mark a method as a 'forward' method to prevent it bypassing the strategy wrapper (e.g., DDP).\"\"\"\n        if not isinstance(method, (MethodType, str)):\n            raise TypeError(f\"Expected a method or a string, but got: {type(method).__name__}\")\n        name = method if isinstance(method, str) else method.__name__\n        if name == \"forward\":\n            raise ValueError(\"You cannot mark the forward method itself as a forward method.\")\n        if not isinstance(getattr(self._original_module, name, None), MethodType):\n            raise AttributeError(\n                f\"You marked '{name}' as a forward method, but `{type(self._original_module).__name__}.{name}` does not\"\n                f\" exist or is not a method.\"\n            )\n        self._forward_methods.add(name)\n\n    def _redirection_through_forward(self, method_name: str) -> Callable:\n        assert method_name != \"forward\"\n        original_forward = self._original_module.forward\n\n        def wrapped_forward(*args: Any, **kwargs: Any) -> Any:\n            # Unpatch ourselves immediately before calling the method `method_name`\n            # because itself may want to call the real `forward`\n            self._original_module.forward = original_forward","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/fabric/wrappers.py#L150-L186","documentation":"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.","triggerScenarios":"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()).","commonSituations":"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.","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"],"exampleFix":"# before\nfabric_module.mark_forward_method(MyModel.generate)\nfabric_module.mark_forward_method(functools.partial(m.generate, temperature=0.7))\n\n# after\nfabric_module.mark_forward_method('generate')","handlingStrategy":"type-guard","validationCode":"name = method if isinstance(method, str) else getattr(method, '__name__', None)\nassert name and callable(getattr(model, name, None)), 'pass a method name string instead'","typeGuard":"from types import MethodType\nfrom typing import Union\n\ndef as_method_name(m: Union[MethodType, str]) -> str:\n    if isinstance(m, str):\n        return m\n    if isinstance(m, MethodType):\n        return m.__name__\n    raise TypeError(f'Expected MethodType or str, got {type(m).__name__}')","tryCatchPattern":null,"preventionTips":["Prefer passing the method name as a plain string","Retrieve methods from the instance, not the class"],"tags":["pytorch-lightning","fabric","type-mismatch","method-binding"],"backgroundTag":"wrong-argument-type","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}