{"record":{"id":"5e33e6f038482f71","repo":"reflex-dev/reflex","slug":"expected-return-type-of-fn-name-to-be-a-var","errorCode":null,"errorMessage":"Expected return type of {fn.__name__} to be a Var, got {origin}.","messagePattern":"Expected return type of (.+?) to be a Var, got (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/reflex-base/src/reflex_base/vars/base.py","lineNumber":3361,"sourceCode":"    Args:\n        fn: The function to register.\n\n    Returns:\n        The decorator.\n\n    Raises:\n        TypeError: If the return type of the function is not a Var.\n        TypeError: If the Var return type does not have a generic type.\n        ValueError: If a function for the generic type is already registered.\n    \"\"\"\n    types = get_type_hints(fn)\n    return_type = types[\"return\"]\n\n    origin = get_origin(return_type)\n\n    if origin is not Var:\n        msg = f\"Expected return type of {fn.__name__} to be a Var, got {origin}.\"\n        raise TypeError(msg)\n\n    generic_args = get_args(return_type)\n\n    if not generic_args:\n        msg = f\"Expected Var return type of {fn.__name__} to have a generic type.\"\n        raise TypeError(msg)\n\n    generic_type = get_origin(generic_args[0]) or generic_args[0]\n\n    if generic_type in dispatchers:\n        msg = f\"Function for {generic_type} already registered.\"\n        raise ValueError(msg)\n\n    dispatchers[generic_type] = fn\n\n    return fn\n\n","sourceCodeStart":3343,"sourceCodeEnd":3379,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/packages/reflex-base/src/reflex_base/vars/base.py#L3343-L3379","documentation":"Raised by the dispatcher-registration helper when a function annotated to overload Var operators does not return a Var (or a generic Var[...]). The decorator validates return annotations to build the operator dispatch table.","triggerScenarios":"Decorating a function whose return annotation is e.g. -> int or -> str (not -> Var[int]) with the internal operator-dispatch decorator in reflex.vars.base.","commonSituations":"Extending reflex's reactive operators with a custom dispatch function and forgetting to annotate the return as Var[T].","solutions":["Annotate the return type as Var[SomeType], e.g. def fn(x: Var[int]) -> Var[int]: ...","If you don't need a custom dispatch, use existing operators instead of the registration API"],"exampleFix":"# before\ndef sqrt_op(v: Var[float]):\n    return v.to_operator('sqrt')\n# after\ndef sqrt_op(v: Var[float]) -> Var[float]:\n    return v.to_operator('sqrt')","handlingStrategy":"type-guard","validationCode":"from typing import get_origin, get_args\nfrom reflex.vars import Var\norigin = get_origin(fn.__annotations__['return'])\nassert origin is Var, f'return must be Var[...], got {origin}'","typeGuard":"def returns_var(fn) -> bool:\n    from typing import get_origin\n    from reflex.vars import Var\n    return get_origin(fn.__annotations__.get('return')) is Var","tryCatchPattern":null,"preventionTips":["Annotate every custom operator function with Var[...] return types","Type-check extension modules with pyright before runtime"],"tags":["reflex","type-annotation","operator-dispatch"],"backgroundTag":"missing-type-annotation","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}