{"record":{"id":"7e0ff837a952374b","repo":"D4Vinci/Scrapling","slug":"session-session-id-not-found-available-avai","errorCode":null,"errorMessage":"Session '{session_id}' not found. Available: {available}","messagePattern":"Session '(.+?)' not found\\. Available: (.+?)","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"scrapling/spiders/session.py","lineNumber":80,"sourceCode":"        if session and self._default_session_id == session_id:\n            self._default_session_id = next(iter(self._sessions), None)\n\n        return session\n\n    @property\n    def default_session_id(self) -> str:\n        if self._default_session_id is None:\n            raise RuntimeError(\"No sessions registered\")\n        return self._default_session_id\n\n    @property\n    def session_ids(self) -> list[str]:\n        return list(self._sessions.keys())\n\n    def get(self, session_id: str) -> Session:\n        if session_id not in self._sessions:\n            available = \", \".join(self._sessions.keys())\n            raise KeyError(f\"Session '{session_id}' not found. Available: {available}\")\n        return self._sessions[session_id]\n\n    async def start(self) -> None:\n        \"\"\"Start all sessions that aren't already alive.\"\"\"\n        if self._started:\n            return\n\n        for sid, session in self._sessions.items():\n            if sid not in self._lazy_sessions and not session._is_alive:\n                await session.__aenter__()\n\n        self._started = True\n\n    async def close(self) -> None:\n        \"\"\"Close all registered sessions.\"\"\"\n        for sid, session in self._sessions.items():\n            if sid in self._lazy_sessions and not session._is_alive:\n                continue","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/spiders/session.py#L62-L98","documentation":"SessionManager.get() raises KeyError when the requested session_id is unknown, and the message helpfully lists all registered ids ('Available: ...'). Requests name a session explicitly; an unregistered name cannot be routed, so the manager refuses rather than guessing.","triggerScenarios":"Request(url, session='browser') when only an 'http' session exists; calling manager.get('default') before any add(); using a session id from old code after it was renamed in config.","commonSituations":"Renaming sessions in config without updating request code; conditional registration (e.g. only register a browser session when a flag is set) while requests still reference it.","solutions":["Read the 'Available:' list in the error message and align the id with what was registered.","Check membership first: if name in manager.session_ids.","Define session ids as constants shared between setup and request code.","When registration is conditional, register an HTTP fallback with the same id so requests never 404 at the session layer."],"exampleFix":"# before\nRequest(url, session='browser')  # KeyError: only 'http' registered\n\n# after\nRequest(url, session='http')","handlingStrategy":"validation","validationCode":"if session_name not in manager.session_ids:\n    raise ValueError(\n        f'unknown session {session_name!r}; registered: {manager.session_ids}'\n    )\nRequest(url, session=session_name)","typeGuard":null,"tryCatchPattern":"try:\n    session = manager.get(session_name)\nexcept KeyError as e:\n    logger.error('%s', e)  # message lists available ids\n    session = manager.get(manager.default_session_id)  # optional fallback","preventionTips":["Use shared constants for session ids between registration and request sites.","When registration is conditional, register a fallback session under the same id."],"tags":["session","key-error","routing","configuration"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}