JuliusBrussee/caveman · error · TypeError
AutoGen requires a stable Caveman Scope for each agent or…
Error message
AutoGen requires a stable Caveman Scope for each agent or model context
What it means
The Caveman AutoGen middleware adapter requires an explicit Scope object to be passed alongside the runtime; the Scope anchors recovery sessions and config so each agent or model context has a stable identity. _check() raises this TypeError immediately at construction time when the scope argument is anything other than a caveman Scope instance (e.g. None, a string name, or a dict).
Solutions
- Create and pass a caveman Scope instance (from caveman_middleware import Scope; scope = Scope(...)) to the adapter constructor.
- If a scope name/config is stored elsewhere, reconstruct a Scope from it before constructing the client/workbench.
- Verify the imported Scope comes from caveman_middleware, not another package or an older major version.
- Check that no code path passes scope=None as a default; make scope a required constructor argument in your wrapper.
Example fix
// before
client = CavemanChatCompletionClient(inner_client, runtime=runtime, scope=None)
// after
from caveman_middleware import Scope
scope = Scope("agent-primary")
client = CavemanChatCompletionClient(inner_client, runtime=runtime, scope=scope) Defensive patterns
Strategy: type-guard
Validate before calling
from caveman_middleware import Scope
if not isinstance(scope, Scope):
raise TypeError(f"scope must be a caveman Scope, got {type(scope).__name__}") Type guard
def is_scope(obj) -> bool:
from caveman_middleware import Scope
return isinstance(obj, Scope) Try / catch
try:
client = CavemanChatCompletionClient(inner, runtime=rt, scope=maybe_scope)
except TypeError as e:
if "stable Caveman Scope" in str(e):
client = CavemanChatCompletionClient(inner, runtime=rt, scope=Scope(default_name))
else:
raise Prevention
- Make scope a required keyword argument in your agent factory so it can never default to None.
- Construct Scope objects next to runtime setup, not inline at call sites.
- Add an isinstance(scope, Scope) assert in shared construction helpers.
When it happens
Trigger: Constructing CavemanChatCompletionClient or CavemanWorkbench (which both call _check via their __init__) with scope=None, with a string identifier, or with an object from a different library that is not caveman_middleware's Scope class.
Common situations: Passing a config dict instead of a Scope; forgetting to create a Scope after upgrading the middleware; building agents dynamically in loops and defaulting scope to None; mixing Scope classes from different caveman package versions.
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
- Agno scope resolver must return a Caveman Scope
- Expected an AutoGen ChatCompletionClient
- Expected an AutoGen Workbench or list of workbenches
- LiteLLM scope must be a trusted Caveman Scope
- Pydantic AI scope resolver must return a Caveman Scope
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/0e4cb7be11f62d84.
Report an issue: GitHub.
Appendix: source
Thrown at packages/middleware/python/caveman_middleware/autogen.py:79
def _runtime(key):
try:
return _component_runtimes.get()[key]
except KeyError:
raise ValueError(f"Bind runtime {key!r} with caveman_middleware.autogen.component_runtimes before loading") from None
def _supported(runtime):
return supports_framework(runtime, ("autogen-core", "0.7", "0.8"), ("autogen-agentchat", "0.7", "0.8"), ("autogen-ext", "0.7", "0.8"))
def _version_supported():
return matches_framework(("autogen-core", "0.7", "0.8"), ("autogen-agentchat", "0.7", "0.8"), ("autogen-ext", "0.7", "0.8"))
def _check(runtime, scope):
if not isinstance(scope, Scope):
raise TypeError("AutoGen requires a stable Caveman Scope for each agent or model context")
return runtime.as_async() if isinstance(runtime, MiddlewareRuntime) else runtime
def _schema():
parameters = copy.deepcopy(RECOVERY_SCHEMA)
# AutoGen's OpenAI structured-output helper rejects every non-strict tool,
# even when that tool is not called. A stable strict schema remains usable
# on typed calls; those calls still use only recovery-free transformations.
parameters["required"] = list(parameters["properties"])
return {"name": "caveman_retrieve", "description": RECOVERY_DESCRIPTION,
"parameters": parameters, "strict": True}
def _observed_usage(result):
if result is None or result.cached:
return None
# Native AutoGen converts an absent provider usage block to two zeros.
# Preserve its CreateResult, but do not book those defaults as measurement.View on GitHub (pinned to 3ee70a1026)