langchain-ai/deepagents · error · ValueError
Invalid sort_order {sort_order!r}; expected 'updated_at' or
Error message
Invalid sort_order {sort_order!r}; expected 'updated_at' or 'created_at' What it means
save_thread_sort_order persists the thread-selector sort preference and only accepts 'updated_at' or 'created_at'. Any other value raises ValueError("Invalid sort_order {sort_order!r}; expected 'updated_at' or 'created_at'"). The library validates up front so the TOML config never holds an unusable sort key.
Source
Thrown at libs/code/deepagents_code/model_config.py:6337
def save_thread_sort_order(sort_order: str, config_path: Path | None = None) -> bool:
"""Save the sort order preference for the thread selector.
Args:
sort_order: `"updated_at"` or `"created_at"`.
config_path: Path to config file.
Returns:
True if save succeeded, False on I/O error.
Raises:
ValueError: If `sort_order` is not a recognised value.
"""
if sort_order not in {"updated_at", "created_at"}:
msg = (
f"Invalid sort_order {sort_order!r}; expected 'updated_at' or 'created_at'"
)
raise ValueError(msg)
if config_path is None:
config_path = DEFAULT_CONFIG_PATH
try:
with _config_write_lock:
config_path.parent.mkdir(parents=True, exist_ok=True)
if config_path.exists():
with config_path.open("rb") as f:
data = tomllib.load(f)
else:
data = {}
if "threads" not in data:
data["threads"] = {}
data["threads"]["sort_order"] = sort_order
fd, tmp_path = tempfile.mkstemp(dir=config_path.parent, suffix=".tmp")
try:
with os.fdopen(fd, "wb") as f:
tomli_w.dump(data, f)
Path(tmp_path).replace(config_path)View on GitHub (pinned to a1af029e6e)
Solutions
- Pass exactly 'updated_at' or 'created_at'; map UI labels to these canonical values before saving.
- Normalize with sort_order.lower() and validate against {'updated_at','created_at'} before the call.
- Migrate/ignore legacy persisted sort values instead of re-saving them.
Example fix
// before
save_thread_sort_order(ui_label) # e.g. "name"
// after
if ui_label not in {"updated_at", "created_at"}:
ui_label = "updated_at"
save_thread_sort_order(ui_label) Defensive patterns
Strategy: validation
Validate before calling
VALID_SORT_ORDERS = {"updated_at", "created_at"}
if sort_order not in VALID_SORT_ORDERS:
sort_order = "updated_at" # safe default before saving Try / catch
try:
save_thread_sort_order(sort_order)
except ValueError as exc:
logging.warning("%s; using default", exc)
save_thread_sort_order("updated_at") Prevention
- Define a single SortOrder Literal/enum in your app and derive UI options from it.
- Map UI labels to canonical snake_case values at the boundary.
- Migrate legacy persisted values once at load time.
When it happens
Trigger: Calling save_thread_sort_order("name"), save_thread_sort_order("updatedAt"), or any string outside {'updated_at','created_at'} (case-sensitive), with an optional config_path.
Common situations: Binding a UI toggle to a different label set ('name', 'asc') without mapping; camelCase vs snake_case mixups; older persisted values from a previous schema being re-saved.
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
- Invalid recent startup mode: {mode!r}
- Invalid scope {scope!r}; expected 'cwd' or 'all'
- modes can only be provided when agent is a factory
- models can only be provided when agent is a factory
- -32602
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/67b98f8edc8a6b52.
Report an issue: GitHub.