{"record":{"id":"7611ab00b1c8c5c6","repo":"langchain-ai/deepagents","slug":"server-configuration-changed-after-the-workspace-w","errorCode":null,"errorMessage":"Server configuration changed after the workspace was bound.","messagePattern":"Server configuration changed after the workspace was bound\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/server_graph.py","lineNumber":584,"sourceCode":"    if runtime is not None:\n        _workspace_runtimes.move_to_end(binding.resource_key)\n        return runtime\n    lock = _workspace_runtime_locks.setdefault(binding.resource_key, asyncio.Lock())\n    async with lock:\n        runtime = _workspace_runtimes.get(binding.resource_key)\n        if runtime is None:\n            config = ServerConfig.from_env()\n            current_config = dataclasses.replace(\n                config,\n                cwd=binding.cwd,\n                project_root=binding.project_root,\n            )\n            if (\n                current_config.workspace_fingerprint() != binding.config_fingerprint\n                or current_config.to_workspace_payload() != binding.workspace_config()\n            ):\n                msg = \"Server configuration changed after the workspace was bound.\"\n                raise RuntimeError(msg)\n            config = current_config\n            project_context = ProjectContext(\n                user_cwd=Path(binding.cwd),\n                project_root=Path(binding.project_root)\n                if binding.project_root\n                else None,\n            )\n            runtime = await _make_graphs(\n                config_override=config,\n                project_context_override=project_context,\n            )\n            _workspace_runtimes[binding.resource_key] = runtime\n            if len(_workspace_runtimes) > _MAX_WORKSPACE_RUNTIMES:\n                evicted_key, _ = _workspace_runtimes.popitem(last=False)\n                _workspace_runtime_locks.pop(evicted_key, None)\n    return runtime\n\n","sourceCodeStart":566,"sourceCodeEnd":602,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/server_graph.py#L566-L602","documentation":"RuntimeError raised when the server configuration in effect differs from the configuration fingerprint captured when the thread's workspace was bound. Workspace bindings are keyed to a specific config snapshot; silently applying a changed config could point the thread at different workspace paths, so the runtime rejects it.","triggerScenarios":"Calling make_graph (via _workspace_runtime) for a thread whose binding exists but whose current config's workspace_fingerprint() or to_workspace_payload() no longer match the bound values — i.e. config was edited/overridden between binding and execution.","commonSituations":"Editing server/workspace config (paths, workspace settings) while a session is live; different processes or reloads using divergent configs for the same thread id; test setups that mutate config after binding (see test_rejects_server_config_drift).","solutions":["Rebind the thread's workspace under the new configuration (clear/recreate the binding), then retry","Revert the config change so it matches the fingerprint at bind time","Restart the session/thread so binding and config are captured together","Keep workspace-related config immutable for the lifetime of a bound thread"],"exampleFix":"// before\n# config edited after thread bound\nagent = await make_graph(config_with_thread, current_mutated_config)\n\n// after\n# rebind workspace with the new config first, then execute\nawait rebind_thread_workspace(thread_id, new_config)\nagent = await make_graph(config_with_thread, new_config)","handlingStrategy":"try-catch","validationCode":"from deepagents_code.server_graph import current_workspace_fingerprint\nbinding = get_thread_binding(thread_id)\nif binding and current_config.workspace_fingerprint() != binding.config_fingerprint:\n    rebind_thread_workspace(thread_id, current_config)  # rebind before executing","typeGuard":null,"tryCatchPattern":"try:\n    agent = await make_graph(config, server_config)\nexcept RuntimeError as e:\n    if \"configuration changed\" in str(e):\n        await rebind_thread_workspace(thread_id, server_config)\n        agent = await make_graph(config, server_config)\n    else:\n        raise","preventionTips":["Treat workspace config as immutable for the life of a bound thread","If config must change, explicitly rebind the workspace first","Avoid sharing thread ids across processes with divergent configs","Log config fingerprints per thread to spot drift early"],"tags":["workspace","configuration","drift","session"],"backgroundTag":"config-drift-detected","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}