{"record":{"id":"158486dfb888f35a","repo":"langchain-ai/deepagents","slug":"unknown-keys-in-harnessprofileconfig-dict-sorted","errorCode":null,"errorMessage":"Unknown keys in HarnessProfileConfig dict: {sorted(unknown)}","messagePattern":"Unknown keys in HarnessProfileConfig dict: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/profiles/harness/harness_profiles.py","lineNumber":396,"sourceCode":"            data: A mapping with any subset of the serializable\n                `HarnessProfileConfig` fields. Unknown keys raise `TypeError`.\n\n        Returns:\n            A new `HarnessProfileConfig` populated from `data`.\n\n        Raises:\n            TypeError: If `data` contains unknown keys or fields of the wrong\n                shape.\n            ValueError: If any `excluded_middleware` entry violates the\n                grammar rules enforced in `__post_init__` (empty/whitespace\n                strings, class-path `module:Class` entries, or\n                underscore-prefixed names), or names required scaffolding\n                middleware.\n        \"\"\"\n        unknown = set(data.keys()) - _HARNESS_PROFILE_CONFIG_KEYS\n        if unknown:\n            msg = f\"Unknown keys in HarnessProfileConfig dict: {sorted(unknown)}\"\n            raise TypeError(msg)\n        return cls(\n            base_system_prompt=_coerce_str_or_none(data.get(\"base_system_prompt\"), \"base_system_prompt\"),\n            system_prompt_suffix=_coerce_str_or_none(data.get(\"system_prompt_suffix\"), \"system_prompt_suffix\"),\n            tool_description_overrides=_coerce_str_mapping(data.get(\"tool_description_overrides\"), \"tool_description_overrides\"),\n            excluded_tools=_coerce_frozen_strset(data.get(\"excluded_tools\"), \"excluded_tools\"),\n            excluded_middleware=_coerce_frozen_strset(data.get(\"excluded_middleware\"), \"excluded_middleware\"),\n            general_purpose_subagent=_coerce_general_purpose_subagent(data.get(\"general_purpose_subagent\")),\n        )\n\n    def to_harness_profile(self) -> HarnessProfile:\n        \"\"\"Convert this declarative config into a runtime `HarnessProfile`.\n\n        `excluded_middleware` entries are passed through as name-based\n        exclusions matched against `AgentMiddleware.name`.\n\n        !!! note \"Intentional asymmetry with `from_harness_profile`\"\n\n            This direction is currently lossless because `HarnessProfileConfig`","sourceCodeStart":378,"sourceCodeEnd":414,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/profiles/harness/harness_profiles.py#L378-L414","documentation":"HarnessProfileConfig.from_dict() strictly validates that every key in the input dict is a known config field. Any key not in _HARNESS_PROFILE_CONFIG_KEYS raises a TypeError listing the offending keys. This fails fast so serialized profile dicts with stale or misspelled fields are rejected instead of silently ignored.","triggerScenarios":"Calling HarnessProfileConfig.from_dict(...) with a dict containing keys outside the declared config fields — e.g. typos, runtime-only fields like `extra_middleware`, or keys removed in a newer library version.","commonSituations":"Hand-editing a serialized profile dict and misspelling a field; loading a profile JSON saved by an older/newer deepagents version where fields were renamed or removed; trying to round-trip a HarnessProfile through from_dict including runtime-only middleware fields.","solutions":["Remove the unknown keys from the dict (or fix their spelling) before calling from_dict.","If the key is `extra_middleware` or another runtime-only field, keep it on the HarnessProfile object instead of the serializable HarnessProfileConfig.","If the dict came from an older version, regenerate it via HarnessProfileConfig.to_dict() so keys match the current schema."],"exampleFix":"// before\nconfig = HarnessProfileConfig.from_dict({\"base_system_prompt\": \"x\", \"excluded_middlewares\": [\"a\"]})\n// after\nconfig = HarnessProfileConfig.from_dict({\"base_system_prompt\": \"x\", \"excluded_middleware\": [\"a\"]})","handlingStrategy":"validation","validationCode":"_ALLOWED = _HARNESS_PROFILE_CONFIG_KEYS\nunknown = set(data.keys()) - _ALLOWED\nif unknown:\n    raise TypeError(f\"Unknown keys: {sorted(unknown)}\")\nconfig = HarnessProfileConfig.from_dict(data)","typeGuard":"def is_valid_config_dict(data: object) -> TypeGuard[dict[str, Any]]:\n    return isinstance(data, dict) and set(data.keys()) <= _HARNESS_PROFILE_CONFIG_KEYS","tryCatchPattern":"try:\n    config = HarnessProfileConfig.from_dict(data)\nexcept TypeError as e:\n    if \"Unknown keys\" in str(e):\n        data = {k: v for k, v in data.items() if k in _HARNESS_PROFILE_CONFIG_KEYS}\n        config = HarnessProfileConfig.from_dict(data)\n    else:\n        raise","preventionTips":["Always generate config dicts with HarnessProfileConfig.to_dict() rather than hand-writing keys.","Validate saved profile JSON against the current schema after library upgrades.","Keep runtime-only fields like extra_middleware off the serialized dict."],"tags":["python","validation","configuration","schema"],"backgroundTag":"unknown-config-key","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}