{"id":"0b76094f53b9df44","repo":"pydantic/pydantic","slug":"validate-call-type","errorCode":"validate-call-type","errorMessage":"Input function `{function}` doesn't have a valid signature","messagePattern":"Input function `(.+?)` doesn't have a valid signature","errorType":"exception","errorClass":"PydanticUserError","httpStatus":null,"severity":"error","filePath":"pydantic/validate_call_decorator.py","lineNumber":31,"sourceCode":"\n__all__ = ('validate_call',)\n\nif TYPE_CHECKING:\n    from .config import ConfigDict\n\n    AnyCallableT = TypeVar('AnyCallableT', bound=Callable[..., Any])\n\n\n_INVALID_TYPE_ERROR_CODE = 'validate-call-type'\n\n\ndef _check_function_type(function: object) -> None:\n    \"\"\"Check if the input function is a supported type for `validate_call`.\"\"\"\n    if isinstance(function, _generate_schema.VALIDATE_CALL_SUPPORTED_TYPES):\n        try:\n            _typing_extra.signature_no_eval(cast(_generate_schema.ValidateCallSupportedTypes, function))\n        except (ValueError, TypeError):\n            raise PydanticUserError(\n                f\"Input function `{function}` doesn't have a valid signature\", code=_INVALID_TYPE_ERROR_CODE\n            )\n\n        if isinstance(function, partial):\n            try:\n                assert not isinstance(partial.func, partial), 'Partial of partial'\n                _check_function_type(function.func)\n            except PydanticUserError as e:\n                raise PydanticUserError(\n                    f'Partial of `{function.func}` is invalid because the type of `{function.func}` is not supported by `validate_call`',\n                    code=_INVALID_TYPE_ERROR_CODE,\n                ) from e\n\n        return\n\n    if isinstance(function, BuiltinFunctionType):\n        raise PydanticUserError(f'Input built-in function `{function}` is not supported', code=_INVALID_TYPE_ERROR_CODE)\n    if isinstance(function, (classmethod, staticmethod, property)):","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/pydantic/pydantic/blob/2e5f0e2b4218de31709f1cf9c5bc61ea97a68835/pydantic/validate_call_decorator.py#L13-L49","documentation":"Raised by pydantic.validate_call_decorator._check_function_type (pydantic/validate_call_decorator.py:31) when the object IS one of the supported callables (lambda, function, method, or functools.partial) but inspecting its signature via _typing_extra.signature_no_eval raises ValueError or TypeError. validate_call needs a resolvable signature to build per-argument validators; without one it cannot construct the wrapper. This is a PydanticUserError with code 'validate-call-type'.","triggerScenarios":"Applying @validate_call to a function whose signature cannot be introspected at decoration time: functions with unresolvable PEP 563 string forward references when the referenced name is unavailable in the namespace; Cython-compiled functions lacking a usable __signature__; functions decorated in a context where a referenced type was never imported; dynamically-generated functions with synthetic/broken __wrapped__ chains.","commonSituations":"Enabling from __future__ import annotations and referencing a type only imported under TYPE_CHECKING; decorating methods of classes defined later in the module; wrapping compiled extension functions; IDE refactors that drop an import the signature still references.","solutions":["Ensure every type referenced in the function signature is imported at runtime in the same module/namespace where @validate_call runs.","If using from __future__ import annotations, move the referenced types out of TYPE_CHECKING-only blocks or import them eagerly.","For compiled/Cython callables, wrap them in a thin pure-Python function whose signature is explicit.","Add the missing import or replace an unresolvable annotation with typing.Any as a last resort."],"exampleFix":"// before\nfrom __future__ import annotations\nfrom typing import TYPE_CHECKING\nif TYPE_CHECKING:\n    from mypkg import MyType\n\n@validate_call\ndef f(x: MyType) -> None: ...  # MyType unresolvable at runtime -> error\n\n// after\nfrom __future__ import annotations\nfrom mypkg import MyType  # imported eagerly\n\n@validate_call\ndef f(x: MyType) -> None: ...","handlingStrategy":"type-guard","validationCode":"import inspect\nfrom pydantic._internal import _typing_extra\n\ndef has_introspectable_signature(func) -> bool:\n    try:\n        _typing_extra.signature_no_eval(func)\n        return True\n    except (ValueError, TypeError):\n        return False","typeGuard":"import inspect\nfrom types import FunctionType, MethodType, LambdaType\nfrom functools import partial\n\ndef is_validate_call_supported(obj) -> bool:\n    return isinstance(obj, (LambdaType, FunctionType, MethodType, partial)) and has_introspectable_signature(obj)","tryCatchPattern":"from pydantic.errors import PydanticUserError\n\ntry:\n    @validate_call\n    def f(x: int): ...\nexcept PydanticUserError as e:\n    if e['code'] == 'validate-call-type':\n        # resolve missing forward refs / wrap a builtin, then retry\n        ...","preventionTips":["Import every type used in a @validate_call signature eagerly, not under TYPE_CHECKING.","Add a unit test that imports the module so the decorator runs and signature resolution is verified.","Avoid from __future__ import annotations in modules that use @validate_call with complex refs, or ensure refs resolve at runtime."],"tags":["validate-call","signature","type-annotation","forward-reference"],"analyzedSha":"2e5f0e2b4218de31709f1cf9c5bc61ea97a68835","analyzedAt":"2026-08-04T19:54:21.281Z","schemaVersion":2}