{"record":{"id":"77436718e8387bf1","repo":"langchain-ai/deepagents","slug":"session-load-requires-an-agent-compiled-with-a-che","errorCode":null,"errorMessage":"session/load requires an agent compiled with a checkpointer","messagePattern":"session/load requires an agent compiled with a checkpointer","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"libs/acp/deepagents_acp/server.py","lineNumber":810,"sourceCode":"    def _session_config(self, session_id: str) -> RunnableConfig:\n        \"\"\"Build the LangGraph config and durable metadata for an ACP session.\"\"\"\n        metadata = {\n            _ACP_SESSION_METADATA_KEY: True,\n            \"cwd\": self._session_cwds[session_id],\n        }\n        if session_id in self._session_modes:\n            metadata[_ACP_MODE_METADATA_KEY] = self._session_modes[session_id]\n        if session_id in self._session_models:\n            metadata[_ACP_MODEL_METADATA_KEY] = self._session_models[session_id]\n        return {\"configurable\": {\"thread_id\": session_id}, \"metadata\": metadata}\n\n    def _checkpointed_agent(self, session_id: str) -> CompiledStateGraph:\n        \"\"\"Return the session agent, requiring a configured checkpointer.\"\"\"\n        if self._agent is None or self._agent_session_id != session_id:\n            self._reset_agent(session_id)\n        if self._agent is None or getattr(self._agent, \"checkpointer\", None) is None:\n            msg = \"session/load requires an agent compiled with a checkpointer\"\n            raise RuntimeError(msg)\n        return self._agent\n\n    async def _persist_session(self, session_id: str) -> None:\n        \"\"\"Write the current ACP session metadata to its checkpoint thread.\"\"\"\n        agent = self._checkpointed_agent(session_id)\n        await agent.aupdate_state(self._session_config(session_id), {}, as_node=\"__start__\")\n\n    async def _replay_session(\n        self,\n        session_id: str,\n        agent: CompiledStateGraph,\n    ) -> None:\n        \"\"\"Replay persisted conversation entries before `session/load` returns.\"\"\"\n        snapshots = [\n            snapshot\n            async for snapshot in agent.aget_state_history(self._session_config(session_id))\n        ]\n        messages: dict[str, Any] = {}","sourceCodeStart":792,"sourceCodeEnd":828,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/acp/deepagents_acp/server.py#L792-L828","documentation":"`_load_effective_config_data` raises `OSError` whose message is the user config's status detail (or health value) when an explicitly requested (non-default) `config.toml` exists but is unusable — typically a TOML parse error or unreadable file. On the default path it degrades to managed-only data with a warning instead, but explicit paths fail hard so callers know their config was not applied.","triggerScenarios":"Calling `load_effort_for_model(path)`, `load_thread_config(path)`, `load_thread_columns(path)`, `load_thread_relative_time(path)`, `load_thread_sort_order(path)` (or `is_warning_suppressed`) with an explicit path to a file that fails to parse (invalid TOML, wrong encoding) or cannot be read (permissions); `detail`/`health` text from `get_config_sources(...).user.status` becomes the exception message.","commonSituations":"Hand-editing `config.toml` and leaving a TOML syntax error (unclosed string, bad table header); a file with invalid UTF-8; a `--config`-style flag pointing at a corrupted or permission-locked file; syncing tools writing partial files.","solutions":["Read the exception message — it contains the parser's specific complaint (line/column for TOML errors)","Fix the TOML syntax at the reported line (common: unclosed quotes/brackets, duplicate keys)","Verify file permissions and encoding (UTF-8) for the config file","Validate the file with a TOML parser (e.g. `python -c \"import tomllib; tomllib.load(open(PATH,'rb'))\"`) before retrying"],"exampleFix":"# before (invalid TOML)\n[models]\nallowed = [\"anthropic:claude-sonnet-4-5\"\n# after (closed bracket)\n[models]\nallowed = [\"anthropic:claude-sonnet-4-5\"]","handlingStrategy":"try-catch","validationCode":"import tomllib\nfrom pathlib import Path\n\ndef config_file_is_usable(path: Path) -> bool:\n    try:\n        tomllib.loads(path.read_text(encoding=\"utf-8\"))\n        return True\n    except (OSError, UnicodeDecodeError, tomllib.TOMLDecodeError):\n        return False","typeGuard":"def status_detail_is_readable(status: object) -> bool:\n    detail = getattr(status, \"detail\", None)\n    return bool(detail) or getattr(getattr(status, \"health\", None), \"value\", None) is not None","tryCatchPattern":"try:\n    data = load_thread_config(explicit_path)\nexcept OSError as exc:\n    logger.error(\"config %s unusable: %s\", explicit_path, exc)\n    data = load_thread_config(None)  # fall back to default-path (managed-aware) read","preventionTips":["Validate `config.toml` with a TOML parser after every manual edit","Write config files atomically (temp file + rename) so readers never see partial content","Ensure UTF-8 encoding and read permissions on config files","On the default path a bad file only warns — check logs for 'Ignoring unusable config file' to catch silent degradation"],"tags":["python","toml","config-file","oserror","io"],"backgroundTag":"config-file-unreadable","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}