{"record":{"id":"c3dc6ceea41032e1","repo":"oraios/serena","slug":"session-id-is-required-in-the-hook-input-data","errorCode":null,"errorMessage":"Session ID is required in the hook input data","messagePattern":"Session ID is required in the hook input data","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/hooks.py","lineNumber":40,"sourceCode":"    \"\"\"The client application that triggered the hook.\"\"\"\n\n    CLAUDE_CODE = \"claude-code\"\n    CODEBUDDY = \"codebuddy\"\n    VSCODE = \"vscode\"\n    CODEX = \"codex\"\n    GROK = \"grok\"\n\n\nclass Hook(ABC):\n    def __init__(self, client: HookClient):\n        raw = sys.stdin.read()\n        input_data = json.loads(raw, strict=False)\n        self._input_data = input_data\n        self._client = client\n\n        session_id = input_data.get(\"session_id\") or input_data.get(\"sessionId\")\n        if not session_id:\n            raise ValueError(\"Session ID is required in the hook input data\")\n        self._session_id = str(session_id)\n        self.session_persistence_dir = os.path.join(serena_home_dir, \"hook_data\", self._session_id)\n        # tool input has a timestamp but using now is enough\n        self.triggered_at_timestamp = datetime.now()\n\n    @abstractmethod\n    def execute(self) -> None:\n        pass\n\n\nclass PreToolUseHook(Hook, ABC):\n    _NON_SYMBOLIC_SERENA_TOOL_NAME_SUBSTRINGS = frozenset(\n        (\n            \"pattern\",\n            \"read\",\n            \"diagnostics\",\n            \"memory\",\n            \"onboarding\",","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/hooks.py#L22-L58","documentation":"SerenaAgentHook.__init__ parses the hook's stdin JSON and requires a session_id (or sessionId) field to build the per-session persistence directory under serena_home/hook_data. If the hook input payload lacks it, ValueError is raised.","triggerScenarios":"A hook client (e.g. Claude Code hook or custom HookClient) invokes a Serena hook with JSON input missing both 'session_id' and 'sessionId' keys, or with null/empty values.","commonSituations":"Writing a custom hook integration that forgets to forward the session id; an agent CLI updating its hook schema/field name; manually testing hooks with hand-crafted JSON.","solutions":["Ensure the hook input JSON includes \"session_id\" (or \"sessionId\") with a non-empty value","Update the agent/hook client to a version that forwards session ids","Validate your hook payload schema before registering hooks"],"exampleFix":"// before\n{\"hook_event_name\": \"PreToolUse\"}\n// after\n{\"hook_event_name\": \"PreToolUse\", \"session_id\": \"abc-123\"}","handlingStrategy":"validation","validationCode":"def validate_hook_input(data: dict) -> None:\n    sid = data.get(\"session_id\") or data.get(\"sessionId\")\n    if not sid:\n        raise ValueError(\"hook input JSON must include a non-empty session_id\")","typeGuard":null,"tryCatchPattern":"try:\n    hook = SerenaAgentHook(client)\nexcept ValueError as e:\n    if \"Session ID\" in str(e):\n        logging.error(\"Hook payload missing session_id: fix the hook client payload\")\n    else:\n        raise","preventionTips":["Always include session_id in hook JSON payloads","Validate hook payload schema in your custom hook client before invoking","Pin agent CLI versions and review changelogs for hook schema changes","Test hooks with a representative full payload, not minimal JSON"],"tags":["python","hooks","validation","config"],"backgroundTag":"missing-required-field","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}