{"record":{"id":"a6d7b32dd60c1037","repo":"NousResearch/hermes-agent","slug":"parent-session-id-does-not-match-the-active-sessio","errorCode":null,"errorMessage":"parent_session_id does not match the active session.","messagePattern":"parent_session_id does not match the active session\\.","errorType":"exception","errorClass":"SubagentLifecycleError","httpStatus":null,"severity":"error","filePath":"agent/subagent_lifecycle.py","lineNumber":207,"sourceCode":"\n    Running children are in-process only.  Completed results remain available\n    until process exit; ``reconnect`` accurately reports that a serialized\n    handle cannot reconnect after a restart instead of launching work again.\n    \"\"\"\n\n    def __init__(self, parent_agent_resolver: Callable[[], Any]) -> None:\n        self._parent_agent_resolver = parent_agent_resolver\n\n    def launch(self, request: SubagentLaunchRequest) -> SubagentHandle:\n        parent = self._parent_agent_resolver()\n        if parent is None:\n            raise SubagentLifecycleError(\n                \"No active Hermes parent session is available.\"\n            )\n        self._validate_request(request, parent)\n        parent_session_id = str(getattr(parent, \"session_id\", \"\") or \"\") or None\n        if request.parent_session_id and request.parent_session_id != parent_session_id:\n            raise SubagentLifecycleError(\n                \"parent_session_id does not match the active session.\"\n            )\n        correlation_key = (parent_session_id, request.correlation_id or \"\")\n        with _REGISTRY.lock:\n            self._cleanup_locked()\n            if request.correlation_id and correlation_key in _REGISTRY.correlations:\n                raise SubagentLifecycleError(\n                    \"Duplicate correlation_id for this parent session.\"\n                )\n\n        # Delegate construction remains internal so plugin code never imports\n        # private delegation helpers or manipulates the active-child registry.\n        from tools.delegate_tool import (\n            _build_child_preserving_parent_tools,\n            DEFAULT_MAX_ITERATIONS,\n        )\n\n        child = _build_child_preserving_parent_tools(","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/agent/subagent_lifecycle.py#L189-L225","documentation":"Raised by SubagentLifecycleManager.launch() when the caller supplies a parent_session_id on the launch request and it differs from the session_id of the actually-resolved parent agent. It is a consistency check tying a launch to the session the caller believes is active.","triggerScenarios":"Passing SubagentLaunchRequest(parent_session_id=<old-id>) after the session was resumed/newed and got a different session_id; caching a request object built under a previous session and replaying it; hardcoding a session id in plugin code.","commonSituations":"Long-lived plugin code that snapshots the session id at startup and reuses it for later launches; resuming a conversation where Hermes assigned a new session_id; multi-session processes (gateway serving several chats) mixing up ids.","solutions":["Omit parent_session_id (leave it None) when you want the launch bound to whatever session is currently active.","If you must pin it, read the live value from the parent agent (parent.session_id) at launch time, not from a cached value.","Discard and rebuild stale SubagentLaunchRequest objects whenever the session changes."],"exampleFix":"# before\nrequest = SubagentLaunchRequest(goal=g, parent_session_id=cached_session_id)\nhandle = manager.launch(request)\n\n# after\nrequest = SubagentLaunchRequest(goal=g, parent_session_id=str(parent.session_id))\nhandle = manager.launch(request)","handlingStrategy":"validation","validationCode":"# simplest: don't pin the session at all\nrequest = SubagentLaunchRequest(goal=goal)  # parent_session_id=None\n\n# or pin to the live value:\nlive = str(getattr(parent, \"session_id\", \"\") or \"\")\nrequest = SubagentLaunchRequest(goal=goal, parent_session_id=live or None)","typeGuard":null,"tryCatchPattern":"try:\n    manager.launch(request)\nexcept SubagentLifecycleError as exc:\n    if \"parent_session_id does not match\" in str(exc):\n        request = dataclasses.replace(request, parent_session_id=None)\n        handle = manager.launch(request)\n    else:\n        raise","preventionTips":["Omit parent_session_id unless you truly need session pinning.","Rebuild launch requests whenever the conversation is resumed or /new fires.","Never cache session ids across session lifecycle events."],"tags":["subagents","delegation","session","validation"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}