langchain-ai/deepagents · warning · ClientHookStopError
User prompt submission stopped by hook
Error message
User prompt submission stopped by hook
What it means
When a UserPromptSubmit hook is registered, execute_task_textual awaits hooks.on_user_prompt before running the agent; if the hook returns an unsuccessful outcome, a ClientHookStopError is raised using the hook's stop_reason (defaulting to this message). This lets user hooks veto prompts before any model call.
Source
Thrown at libs/code/deepagents_code/tui/textual_adapter.py:1829
user_msg.update(message_kwargs)
additional_kwargs = user_msg.get("additional_kwargs")
trusted_kwargs = (
dict(additional_kwargs) if isinstance(additional_kwargs, dict) else {}
)
trusted_kwargs[USER_PROMPT_METADATA_KEY] = user_prompt_metadata(
user_input,
[str(path) for path in mentioned_files],
turn_id=turn_id,
)
user_msg["additional_kwargs"] = trusted_kwargs
messages: list[dict[str, Any]] = []
transcript.append([HumanMessage(content=message_content or "")])
if hooks.has_handlers(HookEvent.USER_PROMPT_SUBMIT):
prompt_outcome = await hooks.on_user_prompt(user_input)
if not prompt_outcome.ok:
from deepagents_code.hooks.client_lifecycle import ClientHookStopError
raise ClientHookStopError(
prompt_outcome.stop_reason
or "User prompt submission stopped by hook"
)
else:
prompt_outcome = PromptOutcome()
await dispatch_hook("session.start", {"thread_id": thread_id})
await dispatch_hook("user.prompt", {})
session_context = hooks.take_pending_context(thread_id=thread_id)
if session_context:
messages.append({"role": "system", "content": "\n\n".join(session_context)})
if prompt_outcome.context:
messages.append(
{"role": "system", "content": "\n\n".join(prompt_outcome.context)}
)
if not prompt_outcome.suppress_original_prompt:
messages.append(user_msg)
stream_input: dict | Command = {
"messages": messages,View on GitHub (pinned to a1af029e6e)
Solutions
- Read prompt_outcome.stop_reason / the raised message to see why the hook rejected the prompt and adjust the input accordingly.
- Fix or relax the hook script so legitimate prompts pass.
- Temporarily disable the USER_PROMPT_SUBMIT hook in settings if it is misbehaving.
- Handle ClientHookStopError in the caller to show the stop reason instead of a generic failure.
Example fix
// before
await execute_task_textual(adapter, user_input) # raises ClientHookStopError
// after
try:
await execute_task_textual(adapter, user_input)
except ClientHookStopError as exc:
adapter._update_status(f"Prompt blocked by hook: {exc}") Defensive patterns
Strategy: try-catch
Try / catch
try:
await execute_task_textual(adapter, user_input)
except ClientHookStopError as exc:
show_status(f"Prompt blocked by hook: {exc}") Prevention
- Test project hooks against representative prompts before enabling them for the team.
- Log hook stop_reason values to make vetoes diagnosable.
- Provide an opt-out flag for USER_PROMPT_SUBMIT hooks during troubleshooting.
When it happens
Trigger: A configured user_prompt_submit hook returns ok=false for the submitted prompt; the submission then aborts with ClientHookStopError carrying the hook's stop_reason.
Common situations: Project hook scripts that block prompts matching policy rules (e.g. secrets, forbidden commands); hooks that fail validation and intentionally stop the turn; misconfigured hooks returning a failed status on valid input.
Related errors
- Session start stopped by hook
- Compact session start stopped by hook
- Server process is not running
- A workspace is required to start the remote agent.
- Permission interrupted by hook
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/caa8503557ffcc10.
Report an issue: GitHub.