langchain-ai/deepagents · error · TypeError
`{field_name}` keys and values must be strings
Error message
`{field_name}` keys and values must be strings What it means
After confirming the value is a Mapping, _coerce_str_mapping checks that every key and value is a str. Any non-string key or value raises a TypeError naming the field. This keeps tool-description override tables strictly str->str.
Source
Thrown at libs/deepagents/deepagents/profiles/harness/harness_profiles.py:838
"""Validate that `value` is a string or `None` for dict-loaded string fields."""
if value is None or isinstance(value, str):
return value
msg = f"`{field_name}` must be str or None, got {type(value).__name__}"
raise TypeError(msg)
def _coerce_str_mapping(value: object, field_name: str) -> dict[str, str]:
"""Validate that `value` is a `str -> str` mapping (or `None`) and return a plain dict."""
if value is None:
return {}
if not isinstance(value, Mapping):
msg = f"`{field_name}` must be a mapping, got {type(value).__name__}"
raise TypeError(msg)
out: dict[str, str] = {}
for key, val in value.items():
if not isinstance(key, str) or not isinstance(val, str):
msg = f"`{field_name}` keys and values must be strings"
raise TypeError(msg)
out[key] = val
return out
def _coerce_frozen_strset(value: object, field_name: str) -> frozenset[str]:
"""Validate that `value` is an iterable of strings (or `None`)."""
if value is None:
return frozenset()
if not isinstance(value, (list, tuple, set, frozenset)):
msg = f"`{field_name}` must be a list/set of strings, got {type(value).__name__}"
raise TypeError(msg)
entries: list[str] = []
for entry in value:
if not isinstance(entry, str):
msg = f"`{field_name}` entries must be strings, got {type(entry).__name__} ({entry!r})"
raise TypeError(msg)
entries.append(entry)
return frozenset(entries)View on GitHub (pinned to a1af029e6e)
Solutions
- Cast keys and values to str before passing them (str(key), str(value)).
- Fix the source data so override entries are string-to-string.
- Reject/repair the config upstream if keys are enums or ints, mapping them to official tool-name strings.
Example fix
// before
overrides = {ToolName.BASH: "Run shell"}
config = HarnessProfileConfig.from_dict({"tool_description_overrides": overrides})
// after
overrides = {str(ToolName.BASH.value): "Run shell"}
config = HarnessProfileConfig.from_dict({"tool_description_overrides": overrides}) Defensive patterns
Strategy: type-guard
Validate before calling
overrides = data.get("tool_description_overrides") or {}
if not all(isinstance(k, str) and isinstance(v, str) for k, v in overrides.items()):
data["tool_description_overrides"] = {str(k): str(v) for k, v in overrides.items()} Type guard
def is_str_mapping(value: object) -> TypeGuard[dict[str, str]]:
return isinstance(value, Mapping) and all(
isinstance(k, str) and isinstance(v, str) for k, v in value.items()
) Try / catch
try:
config = HarnessProfileConfig.from_dict(data)
except TypeError as e:
if "keys and values must be strings" in str(e):
field = str(e).split('`')[1]
data[field] = {str(k): str(v) for k, v in data[field].items()}
config = HarnessProfileConfig.from_dict(data)
else:
raise Prevention
- Use official tool-name strings (not enums or ints) as override keys.
- Quote numeric-looking keys in YAML/JSON configs.
- Validate override tables with is_str_mapping at config load boundaries.
When it happens
Trigger: from_dict/to_dict/from_harness_profile receiving tool_description_overrides like {"bash": 42} (non-str value) or {42: "desc"} (non-str key), e.g. from JSON with numeric keys or enums as keys.
Common situations: JSON object keys serialized from numeric tool IDs; YAML configs where a description was written as a number or boolean; programmatic overrides built with enum or non-str tool names.
Related errors
- `{field_name}` must be a mapping, got {type(value).__name__}
- interpreter_ptc must be False, 'safe', 'all', or a list of t
- max_retries must be an int, got {type(max_retries).__name__}
- stream_output_is_visible must be a bool, got {type(stream_ou
- context.{key} must be a string or null, got {type(value).__n
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/f328c154dda104e5.
Report an issue: GitHub.