langchain-ai/deepagents · error · ValueError
workspace configuration must be JSON serializable
Error message
workspace configuration must be JSON serializable
What it means
`canonical_workspace_config` JSON-serializes the config to produce a canonical fingerprint. This ValueError is raised when the config dict contains values that cannot be JSON-serialized (e.g. sets, datetime objects, custom class instances, non-string dict keys that cannot convert), so no stable fingerprint can be computed.
Source
Thrown at libs/code/deepagents_code/workspace.py:113
def canonical_workspace_config(value: object | None) -> tuple[str, str]:
"""Return bounded canonical JSON and its SHA-256 fingerprint.
Raises:
TypeError: If the configuration is not an object.
ValueError: If it cannot be serialized or exceeds the size limit.
"""
if value is None:
value = {}
if not isinstance(value, dict):
msg = "workspace_config must be an object"
raise TypeError(msg)
try:
serialized = json.dumps(value, sort_keys=True, separators=(",", ":"))
except (TypeError, ValueError) as exc:
msg = "workspace configuration must be JSON serializable"
raise ValueError(msg) from exc
if len(serialized) > _MAX_CONFIG_LENGTH:
msg = "workspace configuration is too large"
raise ValueError(msg)
return serialized, hashlib.sha256(serialized.encode()).hexdigest()
def _fingerprint(value: object) -> str:
serialized = json.dumps(value, sort_keys=True, separators=(",", ":"))
return hashlib.sha256(serialized.encode()).hexdigest()
def resolve_workspace(
cwd: object,
workspace_config: object | None = None,
*,
config_fingerprint: str | None = None,
) -> WorkspaceBinding:
"""Resolve and validate a client workspace claim.View on GitHub (pinned to a1af029e6e)
Solutions
- Convert unserializable values to JSON-native types (str for Path/datetime, list for set) before passing
- Use `json.dumps(workspace_config)` in a pre-check to find the offending value
- Ensure all dict keys are strings
Example fix
// before
cfg = {"deadline": datetime.now(), "roots": {Path("/tmp")}}
// after
cfg = {"deadline": datetime.now().isoformat(), "roots": [str(p) for p in roots]} Defensive patterns
Strategy: validation
Validate before calling
try:
json.dumps(workspace_config, sort_keys=True)
except (TypeError, ValueError) as exc:
raise ValueError(f"workspace_config not JSON serializable: {exc}") from exc Try / catch
try:
bind_thread_workspace(tid, cwd, workspace_config=cfg)
except ValueError as exc:
if "JSON serializable" in str(exc):
cfg = json.loads(json.dumps(cfg, default=str))
bind_thread_workspace(tid, cwd, workspace_config=cfg) Prevention
- Convert Path/datetime/set values to str/list before building config
- Keep configs JSON-round-trippable
- Test `json.dumps(cfg)` in config-loading code
When it happens
Trigger: Calling `canonical_workspace_config`, `bind_thread_workspace`, `resolve_workspace`, or `require_thread_workspace` with a dict containing unserializable values such as `set()`, `datetime.now()`, path objects, or a key of an unsupported type.
Common situations: Passing `Path` objects or datetimes parsed from CLI args in the config; using sets for allowed paths; dict keys that are ints or tuples; configs built from in-memory objects rather than JSON-loaded data.
Related errors
- Invalid {SERVER_ENV_PREFIX}ALLOW_FS_TOOLS value: {raw!r}; ex
- Invalid MCP config at {mcp_config_path}: {exc}
- Workspace policy and fingerprint must be configured together
- External event must be valid JSON: {exc.msg}
- External event kind must be one of {sorted(_VALID_KINDS)}; g
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/ee2368575515025b.
Report an issue: GitHub.