langchain-ai/deepagents · error · WorkspaceConflictError

thread is already bound to a different workspace

Error message

thread {thread_id} is already bound to a different workspace

What it means

`_bind` detects that the thread already has a persisted workspace binding and compares it with the proposed one. This `WorkspaceConflictError` is raised when the existing binding differs (different resource key, cwd/fingerprint, or config fingerprint), i.e. the same thread is being re-bound to a different workspace.

Solutions

  1. Use the workspace the thread was originally bound to (cd back to the original cwd, restore the original config)
  2. Start a new thread for the different workspace instead of rebinding
  3. If the new binding is intentional, clear/rebind via the library's supported reset path or delete the row and rebind

Example fix

// before
bind_thread_workspace(thread_id=tid, cwd="/projects/renamed")  # conflict
// after
bind_thread_workspace(thread_id=tid, cwd="/projects/original")  # or new thread id
Defensive patterns

Strategy: try-catch

Try / catch

try:
    await bind_thread_workspace(tid, cwd, workspace_config=cfg)
except WorkspaceConflictError:
    logging.warning("thread %s already bound elsewhere; starting new thread", tid)
    tid = new_thread_id()
    await bind_thread_workspace(tid, cwd, workspace_config=cfg)

Prevention

When it happens

Trigger: Calling `bind_thread_workspace` for a thread_id already bound, with a different `cwd`, `workspace_config`, or `config_fingerprint`; resuming a session from a moved directory; changing workspace_config between runs of the same thread.

Common situations: Renaming or moving the project directory and re-running the same thread id; editing the workspace config after the first bind; reusing a persisted thread id from a checkpoint in a different checkout; config_fingerprint mismatch after config normalization changed.

Related errors


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

Appendix: source

Thrown at libs/code/deepagents_code/workspace.py:252

                proposed.cwd,
                proposed.project_root,
                proposed.generation,
                proposed.resource_key,
                proposed.config_fingerprint,
                proposed.workspace_config_json,
            ),
        )
        row = conn.execute(
            "SELECT * FROM dcode_thread_workspaces WHERE thread_id = ?",
            (thread_id,),
        ).fetchone()
        if row is None:
            msg = f"workspace binding was not persisted for thread {thread_id}"
            raise RuntimeError(msg)
        existing = _row_binding(row)
        if _binding_differs(existing, proposed):
            msg = f"thread {thread_id} is already bound to a different workspace"
            raise WorkspaceConflictError(msg)
        if not existing.config_fingerprint:
            conn.execute(
                """
                UPDATE dcode_thread_workspaces
                SET schema_version = ?, resource_key = ?, config_fingerprint = ?,
                    workspace_config_json = ?
                WHERE thread_id = ? AND config_fingerprint = ''
                """,
                (
                    proposed.schema_version,
                    proposed.resource_key,
                    proposed.config_fingerprint,
                    proposed.workspace_config_json,
                    thread_id,
                ),
            )
            return proposed
        return existing

View on GitHub (pinned to a1af029e6e)