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
- Pass a non-empty string thread id; convert UUIDs with `str()`
- Ensure the thread/session id is created before binding
- 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
- Convert UUIDs with str() before binding
- Generate the thread id before calling bind
- Never pass empty strings as ids
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
- thread_id is required in config.configurable
- Workspace policy and fingerprint must be configured together
- thread_id path parameter must be non-empty.
- workspace.{field} must be a non-empty absolute path
- workspace.{field} must be an absolute path without traversal
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/ad97e27a54b3b8c3.
Report an issue: GitHub.