langchain-ai/deepagents · error · TypeError
workspace_config must be an object
Error message
workspace_config must be an object
What it means
`canonical_workspace_config` normalizes an optional workspace config into a canonical serialized form plus fingerprint. This library raises this TypeError when the caller passes a non-dict, non-None value (e.g. a list, string, or number) as `workspace_config`, because the config must be a JSON object of key/value settings.
Source
Thrown at libs/code/deepagents_code/workspace.py:108
if os.name != "nt":
from deepagents.backends.utils import validate_path
validate_path(str(resolved))
return resolved
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,View on GitHub (pinned to a1af029e6e)
Solutions
- Ensure the value passed as `workspace_config` is a `dict` (or omitted/None for defaults)
- If loading from a string or file, `json.loads` it first and assert the top level is an object
- If your config is a list, wrap or restructure it under an object key
Example fix
// before
resolve_workspace(cwd, workspace_config=["a", "b"])
// after
resolve_workspace(cwd, workspace_config={"allowed_paths": ["a", "b"]}) Defensive patterns
Strategy: type-guard
Validate before calling
if workspace_config is not None and not isinstance(workspace_config, dict):
raise TypeError("workspace_config must be a dict") Type guard
def is_workspace_config(v: object) -> TypeGuard[dict[str, Any]]:
return v is None or isinstance(v, dict) Try / catch
try:
resolve_workspace(cwd, workspace_config)
except TypeError as exc:
logging.error("bad workspace_config type: %s", exc)
workspace_config = {} Prevention
- Only pass dicts or None as workspace_config
- json.loads string configs before passing
- Validate YAML-loaded configs are mappings at top level
When it happens
Trigger: Calling `canonical_workspace_config` directly, or `bind_thread_workspace` / `resolve_workspace` / `require_thread_workspace`, with `workspace_config` set to a JSON array, string, int, or None-wrapped object instead of a dict (e.g. loading config from YAML that yields a list, or passing `workspace_config='{}'` as a JSON string).
Common situations: Config loaded from a YAML file that parses to a list at top level; JSON config passed as a raw string instead of `json.loads`-ed; a caller wrapping the dict in an extra container; refactored code that changed the config shape.
Related errors
- Server '{server_name}' '{field_name}' must be a list of stri
- 'mcpServers' field must be a dictionary
- context.auto_approve must be a boolean or null, got {type(au
- workspace configuration is too large
- workspace context is required
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/eda87e16b37b50f3.
Report an issue: GitHub.