{"record":{"id":"5225035ee654811b","repo":"langchain-ai/deepagents","slug":"compact-session-start-stopped-by-hook","errorCode":null,"errorMessage":"Compact session start stopped by hook","messagePattern":"Compact session start stopped by hook","errorType":"exception","errorClass":"ClientHookStopError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/client/non_interactive.py","lineNumber":1989,"sourceCode":"        isinstance(message, ToolMessage)\n        and getattr(message, \"name\", None) == \"compact_conversation\"\n        and str(message.content).startswith(\"Conversation compacted.\")\n    ):\n        return None\n    tool_call_id = getattr(message, \"tool_call_id\", None)\n    return tool_call_id if isinstance(tool_call_id, str) and tool_call_id else None\n\n\nasync def _after_headless_compact(state: StreamState) -> None:\n    from deepagents_code.hooks.client_lifecycle import ClientHookStopError\n    from deepagents_code.hooks.models.domain import SessionStartCause\n\n    outcome = await state.hooks.on_session_start(\n        SessionStartCause.COMPACT,\n        model=state.active_model,\n    )\n    if not outcome.ok:\n        raise ClientHookStopError(\n            outcome.stop_reason or \"Compact session start stopped by hook\"\n        )\n\n\nasync def _end_headless_session(\n    state: StreamState,\n    cause: SessionEndCause,\n    *,\n    timeout_seconds: float = SESSION_END_DRAIN_TIMEOUT_SECONDS,\n) -> None:\n    \"\"\"End a headless session without letting Hooks v2 stall process exit.\n\n    Args:\n        state: Active headless stream state.\n        cause: Reason the session ended.\n        timeout_seconds: Maximum time to wait for `SessionEnd` handlers.\n    \"\"\"\n    if state.session_end_fired:","sourceCodeStart":1971,"sourceCodeEnd":2007,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/client/non_interactive.py#L1971-L2007","documentation":"After a headless compaction, `_after_headless_compact` fires `on_session_start` with cause `COMPACT`; if the hook outcome is not ok, it raises `ClientHookStopError` using the hook's `stop_reason` or this default message. This lets hooks veto continuing the session after context compaction.","triggerScenarios":"A compaction occurs during `_stream_agent` and a registered client hook returns `ok=False` from `on_session_start(SessionStartCause.COMPACT)` without a `stop_reason`, producing this default message.","commonSituations":"Budget or policy hooks rejecting post-compaction continuation; hooks that only allow fresh sessions (not COMPACT restarts); a hook implementation bug returning not-ok on the COMPACT cause it did not handle.","solutions":["Inspect the hook's `stop_reason`; if you only see the default text, identify the hook handling `SessionStartCause.COMPACT` and fix or disable it.","Handle the COMPACT cause explicitly in the hook and return ok when continuation is intended.","Catch `ClientHookStopError` around the headless run and finalize session state via the session-end path.","Test hooks against all `SessionStartCause` values (STARTUP, COMPACT)."],"exampleFix":"// before\nasync def on_session_start(cause, model): return HookOutcome(ok=False)\n// after\nasync def on_session_start(cause, model):\n    if cause is SessionStartCause.COMPACT:\n        return HookOutcome(ok=True)\n    return check_policy(model)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from deepagents_code.hooks.client_lifecycle import ClientHookStopError\ntry:\n    await _stream_agent(...)\nexcept ClientHookStopError as exc:\n    if not exc.args[0] or exc.args[0] == \"Compact session start stopped by hook\":\n        find_hook_missing_compact_handling()  # hook returned not-ok without a reason","preventionTips":["Handle `SessionStartCause.COMPACT` explicitly in every session-start hook","Always set `stop_reason` when returning ok=False","Exercise compaction in hook integration tests"],"tags":["hooks","compaction","session-start","headless"],"backgroundTag":"client-hook-stop","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}