{"record":{"id":"980e325998adf068","repo":"langchain-ai/deepagents","slug":"field-name-must-be-a-mapping-got-type-value","errorCode":null,"errorMessage":"`{field_name}` must be a mapping, got {type(value).__name__}","messagePattern":"`(.+?)` must be a mapping, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/profiles/harness/harness_profiles.py","lineNumber":833,"sourceCode":"Derived from the dataclass fields for drift-free parity with the class.\n\"\"\"\n\n\ndef _coerce_str_or_none(value: object, field_name: str) -> str | None:\n    \"\"\"Validate that `value` is a string or `None` for dict-loaded string fields.\"\"\"\n    if value is None or isinstance(value, str):\n        return value\n    msg = f\"`{field_name}` must be str or None, got {type(value).__name__}\"\n    raise TypeError(msg)\n\n\ndef _coerce_str_mapping(value: object, field_name: str) -> dict[str, str]:\n    \"\"\"Validate that `value` is a `str -> str` mapping (or `None`) and return a plain dict.\"\"\"\n    if value is None:\n        return {}\n    if not isinstance(value, Mapping):\n        msg = f\"`{field_name}` must be a mapping, got {type(value).__name__}\"\n        raise TypeError(msg)\n    out: dict[str, str] = {}\n    for key, val in value.items():\n        if not isinstance(key, str) or not isinstance(val, str):\n            msg = f\"`{field_name}` keys and values must be strings\"\n            raise TypeError(msg)\n        out[key] = val\n    return out\n\n\ndef _coerce_frozen_strset(value: object, field_name: str) -> frozenset[str]:\n    \"\"\"Validate that `value` is an iterable of strings (or `None`).\"\"\"\n    if value is None:\n        return frozenset()\n    if not isinstance(value, (list, tuple, set, frozenset)):\n        msg = f\"`{field_name}` must be a list/set of strings, got {type(value).__name__}\"\n        raise TypeError(msg)\n    entries: list[str] = []\n    for entry in value:","sourceCodeStart":815,"sourceCodeEnd":851,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/profiles/harness/harness_profiles.py#L815-L851","documentation":"_coerce_str_mapping validates tool_description_overrides-style fields. If the value is not a Mapping (and not None), a TypeError is raised naming the field and the actual type. This ensures override tables are dict-shaped before per-key string validation.","triggerScenarios":"Passing a list of pairs, a string, or a scalar where a str->str mapping is expected — e.g. from_dict({\"tool_description_overrides\": [(\"bash\", \"Run bash\")]}), to_dict on a profile with a corrupted field, or from_harness_profile with a non-mapping override.","commonSituations":"Building overrides as a list of tuples in Python instead of a dict; YAML/JSON configs where the mapping was accidentally flattened to a string; merging override sources that produced a non-dict value.","solutions":["Pass a plain dict {str: str} for the field.","Convert list-of-pairs input with dict(pairs) before the call.","Fix the config file so the field is a mapping (key: value), not a string or array."],"exampleFix":"// before\nconfig = HarnessProfileConfig.from_dict({\"tool_description_overrides\": [(\"bash\", \"Run shell\")]} )\n// after\nconfig = HarnessProfileConfig.from_dict({\"tool_description_overrides\": {\"bash\": \"Run shell\"}})","handlingStrategy":"type-guard","validationCode":"overrides = data.get(\"tool_description_overrides\")\nif overrides is not None and not isinstance(overrides, Mapping):\n    data[\"tool_description_overrides\"] = dict(overrides) if isinstance(overrides, list) else {}","typeGuard":"def is_str_mapping(value: object) -> TypeGuard[dict[str, str]]:\n    return isinstance(value, Mapping) and all(\n        isinstance(k, str) and isinstance(v, str) for k, v in value.items()\n    )","tryCatchPattern":"try:\n    config = HarnessProfileConfig.from_dict(data)\nexcept TypeError as e:\n    if \"must be a mapping\" in str(e):\n        field = str(e).split('`')[1]\n        data[field] = dict(data[field])\n        config = HarnessProfileConfig.from_dict(data)\n    else:\n        raise","preventionTips":["Build override tables as dicts, never lists of tuples.","Check that config files use key: value mappings for override fields.","Run is_str_mapping on any externally sourced override table before use."],"tags":["python","type-error","validation","mapping"],"backgroundTag":"type-validation-failed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}