langchain-ai/deepagents · error · WorkspaceConflictError
workspace identity changed for thread {thread_id}
Error message
workspace identity changed for thread {thread_id} What it means
After loading a thread's workspace binding, `require_thread_workspace` re-resolves the workspace from the binding's `cwd` + config and compares the resulting `workspace_id` to the one recorded at bind time. A mismatch means the directory/config now resolves to a different workspace identity than the thread was bound to, so the library refuses to run against it via `WorkspaceConflictError` to avoid operating on the wrong workspace.
Source
Thrown at libs/code/deepagents_code/workspace.py:384
and claimed_fingerprint != existing.config_fingerprint
):
msg = f"workspace configuration does not match thread {thread_id}"
raise WorkspaceConflictError(msg)
return existing
existing = await asyncio.to_thread(_require)
if existing.schema_version != _SCHEMA_VERSION:
msg = f"workspace binding schema is unsupported for thread {thread_id}"
raise WorkspaceConflictError(msg)
resolved = await asyncio.to_thread(
resolve_workspace,
existing.cwd,
existing.workspace_config(),
config_fingerprint=existing.config_fingerprint,
)
if resolved.workspace_id != existing.workspace_id:
msg = f"workspace identity changed for thread {thread_id}"
raise WorkspaceConflictError(msg)
return existing
View on GitHub (pinned to a1af029e6e)
Solutions
- Restore the workspace directory/config to match the original binding (undo the rename or revert the config change).
- Delete and recreate the thread's workspace binding so it re-resolves and stores the current `workspace_id`.
- Verify with `resolve_workspace(existing.cwd, existing.workspace_config())` what identity it now produces, and reconcile it with the stored binding.
Example fix
// before: cwd renamed after binding mv ./ws ./ws-renamed // after: keep the bound path stable, or rebind rm binding-for-t-1 await create_thread_workspace(thread_id="t-1", cwd="./ws-renamed")
Defensive patterns
Strategy: try-catch
Try / catch
try:
binding = await require_thread_workspace(thread_id)
except WorkspaceConflictError as e:
if "identity changed" in str(e):
binding = await recreate_binding(thread_id, cwd=current_cwd)
else:
raise Prevention
- Do not move, rename, or reconfigure a workspace directory while threads are bound to it.
- Re-resolve the workspace after any directory/config change and rebind affected threads.
- Keep one canonical workspace path per thread; avoid symlink swapping.
When it happens
Trigger: Calling `make_graph` or `_execute_offload` for a thread whose binding's `cwd` was moved/renamed/replaced, or whose `workspace_config()` / `config_fingerprint` changed so `resolve_workspace` yields a different `workspace_id` than stored.
Common situations: Renaming or replacing the working directory after the thread was created; editing workspace config files; pointing two threads at swapped directories; restoring a directory from a different source.
Related errors
- workspace binding schema is unsupported for thread {thread_i
- thread {thread_id} is already bound to a different workspace
- thread {thread_id} has no workspace binding
- workspace context does not match thread {thread_id}
- workspace configuration does not match thread {thread_id}
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/3c9307f50a067963.
Report an issue: GitHub.