JuliusBrussee/caveman · error · MiddlewareError
invalid_scope
invalid_scope
Error message
invalid_scope
What it means
MiddlewareError raised by scope_key() when any field of a Scope dataclass fails the token() check (must be an int in [0, 9007199254740991] or a valid token string). The scope is serialized to a JSON key for caching/dedup, so every value must be a safe primitive; anything else (floats, bools, None, oversized ints, bad strings) is rejected before it can corrupt cache keys.
Solutions
- Validate/fill every Scope field before calling: ensure ints are in 0..9007199254740991 and strings pass the token charset
- Build scopes via the SDK's own constructors/helpers instead of hand-assembling the dataclass
- Fix the config source that produced None/oversized values and re-run
- Pre-check with the snippet below before making the call
Example fix
# before
scope = Scope(source_id=None, revision=2**60) # invalid_scope
# after
if not (0 <= revision <= 9007199254740991) or source_id is None:
raise ValueError("bad scope fields")
scope = Scope(source_id=source_id, revision=revision) Defensive patterns
Strategy: validation
Validate before calling
def scope_is_valid(scope) -> bool:
from dataclasses import asdict
def tok(v):
return (type(v) is int and 0 <= v <= 9007199254740991) or (isinstance(v, str) and v.isprintable() and v)
return all(tok(v) for v in asdict(scope).values())
# call scope_is_valid(scope) before any API that takes the scope Type guard
def valid_scope_value(v) -> bool:
return type(v) is int and 0 <= v <= 9007199254740991 or isinstance(v, str) and len(v) > 0 Try / catch
try:
result = client.optimize(request, scope=scope)
except MiddlewareError as e:
if e.args[0] == "invalid_scope":
log.error("scope fields must be ints in [0, 2^53-1] or valid tokens")
raise Prevention
- Always build scopes through SDK helpers, never hand-assemble the dataclass
- Validate config-derived scope fields (no None, no floats, no ints > 2^53-1) at load time
- Remember the 2^53-1 limit when interoping with JavaScript numbers
- Unit-test scope construction from every config source
When it happens
Trigger: Calling any public API that takes a Scope (optimize and friends) with a scope containing None, a float, a bool-typed int confusion, an int > 2^53-1, or a negative int in one of its fields — typically a hand-constructed Scope rather than one produced by the library.
Common situations: Constructing Scope manually from parsed config where a field is None or a string number; JavaScript interop writing numbers that exceed 2^53-1; a config file supplying "source_id": null.
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 middleware requires a nonempty native session_id
- Agno scope resolver must return a Caveman Scope
- artifact_id is required
- ASGI context resolver or request bounds are invalid
- assemble requires model and session_id
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/b84f53bcee552f18.
Report an issue: GitHub.
Appendix: source
Thrown at packages/sdk/python/caveman_cloud/middleware/validate.py:30
return hashlib.sha256(text.encode("utf-8")).hexdigest()
def token(value: Any) -> bool:
return isinstance(value, str) and re.fullmatch(r"[a-zA-Z0-9._:/-]{1,256}", value) is not None
def digest(value: Any) -> bool:
return isinstance(value, str) and re.fullmatch(r"[a-f0-9]{64}", value) is not None
def integer(value: Any) -> bool:
return type(value) is int and 0 <= value <= 9007199254740991
def scope_key(scope: Scope) -> str:
values = list(asdict(scope).values())
if not all(token(v) for v in values):
raise MiddlewareError("invalid_scope")
return json.dumps(values, separators=(",", ":"))
def capabilities(value: Any) -> dict[str, Any]:
try:
if (type(value["schema_version"]) is not int or value["schema_version"] != 1 or not token(value["policy_revision"])
or not isinstance(value["runtime_build"], str) or value["mode"] not in ("record", "compress")
or not isinstance(value["transforms"], list) or len(value["transforms"]) > 128
or not all(integer(value["limits"][k]) and value["limits"][k] > 0 for k in ("deadline_ms", "request_bytes", "segment_bytes", "page_bytes"))
or not integer(value["retention_seconds"]) or type(value["recovery"]) is not bool
or type(value["persistent"]) is not bool):
raise ValueError()
seen = set()
for t in value["transforms"]:
if (not token(t["transform_id"]) or t["transform_id"] in seen or not token(t["implementation_version"])
or not isinstance(t["eligible_segment_kinds"], list) or t["recovery"] not in ("exact_ccr", "none") or t["deterministic"] is not True):
raise MiddlewareError("unknown_capability")
seen.add(t["transform_id"])View on GitHub (pinned to 3ee70a1026)