cube-js/cube · error · TemplateException

function registration must be used with functions, actual: '

Error message

function registration must be used with functions, actual: '%s'

What it means

Cube's Python template module raises TemplateException from add_function() when the value passed as a function is not callable. The registry only stores callables so later template evaluation can invoke them safely.

Source

Thrown at packages/cubejs-backend-native/python/cube/src/__init__.py:181

# backward compatibility
settings = config

class TemplateException(Exception):
    pass

class TemplateContext:
    functions: dict[str, Callable]
    variables: dict[str, Any]
    filters: dict[str, Callable]

    def __init__(self):
        self.functions = {}
        self.variables = {}
        self.filters = {}

    def add_function(self, name, func):
        if not callable(func):
            raise TemplateException("function registration must be used with functions, actual: '%s'" % type(func).__name__)

        self.functions[name] = func

    def add_variable(self, name, val):
        if name in self.functions:
            raise TemplateException("unable to register variable: name '%s' is already in use for function" % name)

        self.variables[name] = val

    def add_filter(self, name, func):
        if not callable(func):
            raise TemplateException("function registration must be used with functions, actual: '%s'" % type(func).__name__)

        self.filters[name] = func

    def function(self, func):
        if isinstance(func, str):
            return TemplateFunctionRef(self, func)

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Pass an actual callable: define the function (def or lambda) before registering it.
  2. If you meant a constant value, use add_variable(name, val) instead.
  3. If you registered a string name intending a later lookup, register TemplateFunctionRef or resolve the function first.

Example fix

// before
template.add_function('upper', 'uppercase')
// after
template.add_function('upper', lambda s: s.upper())
Defensive patterns

Strategy: validation

Validate before calling

if not callable(func):
    raise TypeError(f"add_function expects a callable, got {type(func).__name__}")
template.add_function(name, func)

Type guard

def is_callable_fn(x) -> bool:
    return callable(x)

Try / catch

try:
    template.add_function(name, func)
except TemplateException as e:
    log.error('bad function registration: %s', e)

Prevention

When it happens

Trigger: Calling Template.add_function(name, x) where x is not callable — e.g. a string, dict, None, or the result of forgetting to define the function.

Common situations: Typos where the intended function was never defined (NameError avoided by passing a string), passing a lambda-less value, refactoring that replaced a function with a constant.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/952567562e8fbad9. Report an issue: GitHub.