langchain-ai/deepagents · error · ValueError
`mode` must be one of 'thread', 'turn', or 'call'.
Error message
`mode` must be one of 'thread', 'turn', or 'call'.
What it means
The snapshot/middleware `mode` option controls snapshot granularity and must be exactly one of `'thread'`, `'turn'`, or `'call'`. `_resolve_mode` normalizes/validates the value at middleware construction and raises `ValueError` for any other string.
Source
Thrown at libs/partners/quickjs/langchain_quickjs/middleware.py:102
),
)
def _resolve_mode(
*,
mode: str | None,
) -> PersistenceMode:
"""Normalize persistence mode and enforce invariant constraints."""
match mode:
case None | "thread":
return "thread"
case "turn":
return "turn"
case "call":
return "call"
case _:
msg = "`mode` must be one of 'thread', 'turn', or 'call'."
raise ValueError(msg)
def _resolve_thread_id(fallback: str) -> str:
"""Extract `thread_id` from langgraph config or use `fallback`.
The fallback is a middleware-instance-scoped id: when the caller
didn't configure a `thread_id` (common for ad-hoc
`agent.invoke(...)` in tests or single-shot scripts), we still need
all resolver calls within one CodeInterpreterMiddleware lifetime to return the
same id — otherwise `wrap_model_call` installs tools on one REPL
and the eval tool looks up a different one, and the model sees
`ReferenceError: tools is not defined`.
"""
try:
config = get_config()
except RuntimeError:
# Not running inside a Runnable — test / bare-call path.
return fallbackView on GitHub (pinned to a1af029e6e)
Solutions
- Set `mode` to exactly `'thread'`, `'turn'`, or `'call'` (lowercase).
- Validate configuration values before constructing the middleware.
- Use a Literal-typed enum/constants in your config layer to catch typos early.
Example fix
// before QuickJsMiddleware(mode="session") // after QuickJsMiddleware(mode="thread")
Defensive patterns
Strategy: validation
Validate before calling
VALID_MODES = {"thread", "turn", "call"}
if mode not in VALID_MODES:
raise ValueError(f"mode must be one of {sorted(VALID_MODES)}, got {mode!r}") Type guard
def is_valid_mode(mode) -> bool:
return isinstance(mode, str) and mode in {"thread", "turn", "call"} Try / catch
try:
mw = QuickJsMiddleware(mode=cfg["mode"])
except ValueError as e:
if "`mode`" in str(e):
mw = QuickJsMiddleware(mode="thread") # safe default Prevention
- Use the exact lowercase literals 'thread', 'turn', 'call'.
- Type config fields as Literal["thread", "turn", "call"].
- Validate config files before constructing middleware.
When it happens
Trigger: Constructing the middleware (whose `__init__` calls `_resolve_mode`) with `mode="session"`, `mode="Thread"` (wrong case), a misspelled value like `"turns"`, or a non-string value.
Common situations: Typos in configuration files or YAML-driven setup; assuming different casing or synonyms ('session', 'request', 'run'); copying an option from another middleware that uses different mode names.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- HarnessProfile.excluded_middleware is invalid: - required
- `snapshot_signing_key` must be a non-empty str or bytes.
- `max_snapshot_bytes` must be >= 1 or None
- {what} must be absolute: {path}
- Home directory is not absolute: {launch_home}. Set $HOME to
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/3036610f87ea5d5b.
Report an issue: GitHub.