agentscope-ai/agentscope · error · TypeError
factory must be a callable, got {type(factory).__name__}
Error message
factory must be a callable, got {type(factory).__name__} What it means
agentscope's set_id_factory installs a global factory used to generate IDs for entities (messages, blocks, etc.). It requires a no-argument callable; anything non-callable (a string, a class instance, None) raises this TypeError immediately as a fail-fast guard. The factory set here affects every entity ID generated afterwards.
Source
Thrown at src/agentscope/_utils/_common.py:45
startup to substitute a different strategy.
.. note::
Security-sensitive tokens (gateway tokens, Redis lock tokens)
are **not** affected and always use ``uuid.uuid4().hex``.
Args:
factory (`Callable[[], str]`):
A no-arg callable returning a string ID.
Raises:
TypeError: If ``factory`` is not callable.
Example:
>>> from agentscope import set_id_factory
>>> set_id_factory(lambda: uuid7().hex)
"""
if not callable(factory):
raise TypeError(
f"factory must be a callable, got {type(factory).__name__}",
)
global _id_factory
_id_factory = factory
def set_timestamp_factory(factory: Callable[[], str]) -> None:
"""Override the global timestamp factory used by all AgentScope entities.
Args:
factory (`Callable[[], str]`):
A no-arg callable returning a string ID.
Raises:
TypeError: If ``factory`` is not callable.
"""
if not callable(factory):
raise TypeError(View on GitHub (pinned to e90f1c7592)
Solutions
- Pass the callable itself, not its result: set_id_factory(uuid7) or set_id_factory(lambda: uuid7().hex)
- Verify with callable(factory) before setting it
- If the value comes from config, wrap it: set_id_factory(eval-free resolver) or functools.partial for parameterized factories
Example fix
# before set_id_factory(uuid7().hex) # called the function -> passed a str # after set_id_factory(lambda: uuid7().hex)
Defensive patterns
Strategy: type-guard
Validate before calling
if not callable(factory):
raise TypeError(f"expected a callable, got {type(factory).__name__}")
set_id_factory(factory) Type guard
from typing import Callable, TypeGuard
def is_id_factory(v: object) -> TypeGuard[Callable[[], str]]:
return callable(v) Try / catch
try:
set_id_factory(factory)
except TypeError as e:
if "must be a callable" in str(e):
set_id_factory(lambda: uuid7().hex) # sensible default
else:
raise Prevention
- Always pass the function object (uuid7), never its result (uuid7())
- Wrap factories needing arguments in a lambda or functools.partial
- In test suites, reset the factory between tests to avoid leaked global state
When it happens
Trigger: Calling set_id_factory with a non-callable, e.g. set_id_factory("uuid4"), set_id_factory(uuid4()), or set_id_factory(None). Tests like test_custom_factory_affects_entities rely on this contract when injecting custom factories (e.g. lambda: uuid7().hex).
Common situations: Passing the result of calling a factory instead of the factory itself (uuid7() instead of uuid7), passing a UUID string constant, or passing a class name as a string from config. Also hitting stale global state across tests because the factory is a module-level global.
Related errors
- Invalid logging level: {level}. Must be one of 'INFO', 'DEBU
- {key}
- The 'reserve_ratio' of the context config must be smaller th
- The 'context_buffer_ratio' of the injection config must be s
- Channel type '{channel_type}' is not registered; pass it to
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/d7134a3a65cf730b.
Report an issue: GitHub.