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

  1. Restore the workspace directory/config to match the original binding (undo the rename or revert the config change).
  2. Delete and recreate the thread's workspace binding so it re-resolves and stores the current `workspace_id`.
  3. 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

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


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/3c9307f50a067963. Report an issue: GitHub.