langchain-ai/deepagents · error · ValueError

thread_id must be non-empty

Error message

thread_id must be non-empty

What it means

`bind_thread_workspace` validates that `thread_id` is a non-empty string before doing any work. This ValueError means the thread identifier was missing, an empty string, or not a string at all.

Source

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

async def bind_thread_workspace(
    thread_id: str,
    cwd: object,
    workspace_config: object | None = None,
    *,
    config_fingerprint: str | None = None,
) -> WorkspaceBinding:
    """Atomically create or verify a thread workspace binding.

    Returns:
        The immutable binding for the thread.

    Raises:
        ValueError: If the thread is invalid.
    """
    if not isinstance(thread_id, str) or not thread_id:
        msg = "thread_id must be non-empty"
        raise ValueError(msg)
    proposed = await asyncio.to_thread(
        resolve_workspace,
        cwd,
        workspace_config,
        config_fingerprint=config_fingerprint,
    )
    return await asyncio.to_thread(_bind, thread_id, proposed)


async def get_thread_workspace(thread_id: str) -> WorkspaceBinding | None:
    """Read a thread's durable workspace binding.

    Returns:
        The binding, or `None` when the thread is unbound.
    """
    if not isinstance(thread_id, str) or not thread_id:
        return None
    return await asyncio.to_thread(_read, thread_id)

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Pass a non-empty string thread id; convert UUIDs with `str()`
  2. Ensure the thread/session id is created before binding
  3. Add a pre-call check `assert isinstance(tid, str) and tid`

Example fix

// before
bind_thread_workspace(thread_id=session.uuid, cwd=cwd)
// after
bind_thread_workspace(thread_id=str(session.uuid), cwd=cwd)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(thread_id, str) or not thread_id:
    raise ValueError("thread_id must be a non-empty string")

Type guard

def is_valid_thread_id(v: object) -> TypeGuard[str]:
    return isinstance(v, str) and bool(v)

Try / catch

try:
    await bind_thread_workspace(thread_id, cwd)
except ValueError as exc:
    if "thread_id" in str(exc):
        thread_id = str(uuid.uuid4())
        await bind_thread_workspace(thread_id, cwd)

Prevention

When it happens

Trigger: Calling `bind_thread_workspace(thread_id=None)`, `thread_id=""`, or a non-str value (int, UUID object) without converting to string.

Common situations: Thread id not yet generated because session creation failed upstream; passing a UUID object instead of `str(uuid)`; an off-by-one where the variable holding the id was never assigned.

Related errors


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