{"record":{"id":"e72b41c6b73e02dc","repo":"langchain-ai/deepagents","slug":"field-name-must-be-str-or-none-got-type-valu","errorCode":null,"errorMessage":"`{field_name}` must be str or None, got {type(value).__name__}","messagePattern":"`(.+?)` must be str or None, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/profiles/harness/harness_profiles.py","lineNumber":824,"sourceCode":"\nDerived from `HarnessProfileConfig`'s dataclass fields so the set stays in\nsync automatically. Runtime-only fields such as `extra_middleware` are\nabsent because they don't exist on `HarnessProfileConfig`.\n\"\"\"\n\n_GENERAL_PURPOSE_SUBAGENT_KEYS: frozenset[str] = frozenset(f.name for f in fields(GeneralPurposeSubagentProfile))\n\"\"\"Keys accepted by `GeneralPurposeSubagentProfile.from_dict`.\n\nDerived 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","sourceCodeStart":806,"sourceCodeEnd":842,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/profiles/harness/harness_profiles.py#L806-L842","documentation":"_coerce_str_or_none validates fields loaded from a dict via HarnessProfileConfig.from_dict. If a value for a string-typed field (e.g. base_system_prompt, system_prompt_suffix) is neither None nor str, a TypeError is raised naming the field and the actual type. This enforces the declared schema on deserialized configs.","triggerScenarios":"Calling HarnessProfileConfig.from_dict with e.g. {\"base_system_prompt\": 123} or {\"system_prompt_suffix\": [\"part1\"]} — any non-str, non-None value for a string field.","commonSituations":"JSON/YAML configs where a prompt field was given as a list of prompt chunks or a number; template variables left as placeholders of the wrong type; programmatic config builders assigning non-string values.","solutions":["Convert the value to a string before calling from_dict (e.g. str(value) or join list chunks).","Omit the key or pass None if the field should be unset.","Fix the source config file so the field is a quoted string."],"exampleFix":"// before\nconfig = HarnessProfileConfig.from_dict({\"base_system_prompt\": [\"line1\", \"line2\"]})\n// after\nconfig = HarnessProfileConfig.from_dict({\"base_system_prompt\": \"\\n\".join([\"line1\", \"line2\"])})","handlingStrategy":"type-guard","validationCode":"value = data.get(\"base_system_prompt\")\nif value is not None and not isinstance(value, str):\n    value = \"\\n\".join(value) if isinstance(value, list) else str(value)","typeGuard":"def is_str_or_none(value: object) -> TypeGuard[str | None]:\n    return value is None or isinstance(value, str)","tryCatchPattern":"try:\n    config = HarnessProfileConfig.from_dict(data)\nexcept TypeError as e:\n    if \"must be str or None\" in str(e):\n        field = str(e).split('`')[1]\n        data[field] = str(data[field])\n        config = HarnessProfileConfig.from_dict(data)\n    else:\n        raise","preventionTips":["Ensure prompt fields in YAML/JSON are quoted strings, not lists or numbers.","Normalize config input (cast/join) before from_dict.","Add a schema check on config files at load time."],"tags":["python","type-error","validation","deserialization"],"backgroundTag":"type-validation-failed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}