langchain-ai/deepagents · error · RuntimeError
Manual mode could not be persisted
Error message
Manual mode could not be persisted
What it means
After invoking _on_switch_to_manual for a 'switch_manual' decision, a falsy return means the manual mode was not persisted (e.g. the Store write failed). The turn raises RuntimeError because continuing would leave approval state inconsistent with the user's explicit choice.
Source
Thrown at libs/code/deepagents_code/tui/textual_adapter.py:3669
args = action_request.get("args", {})
if isinstance(args, dict):
file_op_tracker.mark_hitl_approved(
tool_name, args
)
elif decision_type == "switch_manual":
if adapter._on_switch_to_manual is None:
msg = "Manual mode callback is unavailable"
raise RuntimeError(msg) # noqa: TRY301 # shared turn error rendering owns this failure
callback_result = adapter._on_switch_to_manual()
switched = (
await callback_result
if inspect.isawaitable(callback_result)
else callback_result
)
if not switched:
msg = "Manual mode could not be persisted"
raise RuntimeError(msg) # noqa: TRY301 # shared turn error rendering owns this failure
decisions = [
cast("HITLDecision", {"type": "switch_manual"})
for _ in action_requests
]
elif decision_type == "approve":
decisions = [
ApproveDecision(type="approve")
for _ in action_requests
]
tool_msgs = _interrupt_tool_rows(
review_namespace,
action_requests,
adapter._current_tool_messages,
)
for tool_msg in tool_msgs:
_set_running_unless_deferred(tool_msg)
adapter._sync_tool_widget(tool_msg)View on GitHub (pinned to a1af029e6e)
Solutions
- Check what _on_switch_to_manual returns and why persistence failed (Store connectivity, permissions) and fix that backend issue.
- Make the callback raise a descriptive error instead of returning False so the root cause is visible.
- Retry the switch once connectivity is restored, then re-submit the pending tool actions.
- Fall back to keeping the current approval mode with a clear UI notice if persistence cannot be guaranteed.
Example fix
// before
def _switch_to_manual():
store.write(mode="manual") # returns False on failure
return False
// after
def _switch_to_manual():
try:
store.write(mode="manual")
return True
except StoreUnavailable as exc:
raise RuntimeError(f"could not persist manual mode: {exc}") from exc Defensive patterns
Strategy: try-catch
Validate before calling
result = adapter._on_switch_to_manual()
result = await result if inspect.isawaitable(result) else result
if not result:
raise StoreWriteError("manual mode persistence returned failure") Try / catch
try:
apply_hitl_decision(adapter, "switch_manual")
except RuntimeError as exc:
render_turn_error(f"switch to manual failed: {exc}")
keep_current_approval_mode() Prevention
- Make switch callbacks raise descriptive errors instead of returning False.
- Log the underlying Store failure inside the callback.
- Add retry-with-backoff to approval-mode persistence writes.
When it happens
Trigger: The 'switch_manual' decision path runs, the callback returns False/None (persistence rejected or Store write failed), and the turn aborts so stale approval semantics are not silently kept.
Common situations: Store outage or write rejection when switching from auto-approve to manual mid-turn; callback implementations returning False on validation failure; async callback returning an awaitable resolving to False.
Related errors
- Approval-mode Store writer is unavailable
- Manual approval mode could not be persisted; graph execution
- Manual mode callback is unavailable
- interpreter_ptc='all' exposes every host tool to PTC calls t
- Provide exactly one of mode or auto_approve
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/a5ab7ae5d1c977c4.
Report an issue: GitHub.