{"record":{"id":"bb6dfb748237710d","repo":"langchain-ai/deepagents","slug":"compact-session-start-stopped-by-hook-bb6dfb","errorCode":null,"errorMessage":"Compact session start stopped by hook","messagePattern":"Compact session start stopped by hook","errorType":"exception","errorClass":"ClientHookStopError","httpStatus":null,"severity":"warning","filePath":"libs/code/deepagents_code/tui/textual_adapter.py","lineNumber":1872,"sourceCode":"    recover_interrupted_turn = not (\n        graph_input is not None and graph_input.get(\"goal_criteria_request\") is not None\n    )\n\n    # Track summarization lifecycle so spinner status and notification stay in sync.\n    summarization_in_progress = False\n    completed_compaction_ids: set[str] = set()\n\n    async def _after_automatic_compact() -> None:\n        from deepagents_code.config import runtime_state\n        from deepagents_code.hooks.client_lifecycle import ClientHookStopError\n        from deepagents_code.hooks.models.domain import SessionStartCause\n\n        outcome = await hooks.on_session_start(\n            SessionStartCause.COMPACT,\n            model=runtime_state.model_name or None,\n        )\n        if not outcome.ok:\n            raise ClientHookStopError(\n                outcome.stop_reason or \"Compact session start stopped by hook\"\n            )\n\n    stream_completed = False\n    try:\n        while True:\n            interrupt_occurred = False\n            suppress_resumed_output = False\n            pending_interrupts: dict[str, tuple[tuple[Any, ...], HITLRequest]] = {}\n            pending_ask_user: dict[str, AskUserRequest] = {}\n            pending_hook_resumes: dict[str, dict[str, Any]] = {}\n\n            if context is None:\n                context = CLIContext()\n            context[\"thread_id\"] = thread_id\n            if turn_id is not None:\n                context[\"turn_id\"] = turn_id\n            else:","sourceCodeStart":1854,"sourceCodeEnd":1890,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/tui/textual_adapter.py#L1854-L1890","documentation":"After an automatic context compaction, _after_automatic_compact fires the SessionStart hook with cause COMPACT. If the hook rejects (outcome.ok is false), a ClientHookStopError is raised with the hook's stop_reason or this default, halting the resumed stream because the post-compact session start was vetoed.","triggerScenarios":"Automatic compaction triggers mid-conversation and the registered session_start hook returns ok=false for the COMPACT cause — the turn aborts right after compaction.","commonSituations":"Session-start hooks that only permit 'startup'/'resume' causes but not 'compact'; a hook script erroring on the compact payload; policy hooks that deny session starts in certain states.","solutions":["Update the session_start hook to accept SessionStartCause.COMPACT.","Check the hook's stop_reason output to see why it denied the compact restart and adjust policy.","Handle ClientHookStopError around execute_task_textual to surface the reason gracefully.","Temporarily disable the session_start hook to unblock the session."],"exampleFix":"// before\n# hook: only allow startup\nif cause != \"startup\": return deny(\"unsupported cause\")\n// after\nif cause not in (\"startup\", \"resume\", \"compact\"):\n    return deny(\"unsupported cause\")","handlingStrategy":"try-catch","validationCode":"if hooks.has_handlers(HookEvent.SESSION_START):\n    probe = await hooks.on_session_start(SessionStartCause.COMPACT, model=model)\n    if not probe.ok:\n        disable_compaction_hooks()","typeGuard":null,"tryCatchPattern":"try:\n    await execute_task_textual(adapter, user_input)\nexcept ClientHookStopError as exc:\n    logger.warning(\"post-compact session start denied: %s\", exc)\n    recover_session()","preventionTips":["Ensure session_start hooks accept all SessionStartCause values, including COMPACT.","Exercise compaction in integration tests when hooks are installed.","Keep hook scripts fast and non-failing for lifecycle events."],"tags":["hooks","compaction","lifecycle"],"backgroundTag":"hook-blocked-prompt","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}