langchain-ai/deepagents · error · TypeError

Unknown keys in HarnessProfileConfig dict: {sorted(unknown)}

Error message

Unknown keys in HarnessProfileConfig dict: {sorted(unknown)}

What it means

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.

Source

Thrown at libs/deepagents/deepagents/profiles/harness/harness_profiles.py:396

            data: A mapping with any subset of the serializable
                `HarnessProfileConfig` fields. Unknown keys raise `TypeError`.

        Returns:
            A new `HarnessProfileConfig` populated from `data`.

        Raises:
            TypeError: If `data` contains unknown keys or fields of the wrong
                shape.
            ValueError: If any `excluded_middleware` entry violates the
                grammar rules enforced in `__post_init__` (empty/whitespace
                strings, class-path `module:Class` entries, or
                underscore-prefixed names), or names required scaffolding
                middleware.
        """
        unknown = set(data.keys()) - _HARNESS_PROFILE_CONFIG_KEYS
        if unknown:
            msg = f"Unknown keys in HarnessProfileConfig dict: {sorted(unknown)}"
            raise TypeError(msg)
        return cls(
            base_system_prompt=_coerce_str_or_none(data.get("base_system_prompt"), "base_system_prompt"),
            system_prompt_suffix=_coerce_str_or_none(data.get("system_prompt_suffix"), "system_prompt_suffix"),
            tool_description_overrides=_coerce_str_mapping(data.get("tool_description_overrides"), "tool_description_overrides"),
            excluded_tools=_coerce_frozen_strset(data.get("excluded_tools"), "excluded_tools"),
            excluded_middleware=_coerce_frozen_strset(data.get("excluded_middleware"), "excluded_middleware"),
            general_purpose_subagent=_coerce_general_purpose_subagent(data.get("general_purpose_subagent")),
        )

    def to_harness_profile(self) -> HarnessProfile:
        """Convert this declarative config into a runtime `HarnessProfile`.

        `excluded_middleware` entries are passed through as name-based
        exclusions matched against `AgentMiddleware.name`.

        !!! note "Intentional asymmetry with `from_harness_profile`"

            This direction is currently lossless because `HarnessProfileConfig`

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Remove the unknown keys from the dict (or fix their spelling) before calling from_dict.
  2. If the key is `extra_middleware` or another runtime-only field, keep it on the HarnessProfile object instead of the serializable HarnessProfileConfig.
  3. If the dict came from an older version, regenerate it via HarnessProfileConfig.to_dict() so keys match the current schema.

Example fix

// before
config = HarnessProfileConfig.from_dict({"base_system_prompt": "x", "excluded_middlewares": ["a"]})
// after
config = HarnessProfileConfig.from_dict({"base_system_prompt": "x", "excluded_middleware": ["a"]})
Defensive patterns

Strategy: validation

Validate before calling

_ALLOWED = _HARNESS_PROFILE_CONFIG_KEYS
unknown = set(data.keys()) - _ALLOWED
if unknown:
    raise TypeError(f"Unknown keys: {sorted(unknown)}")
config = HarnessProfileConfig.from_dict(data)

Type guard

def is_valid_config_dict(data: object) -> TypeGuard[dict[str, Any]]:
    return isinstance(data, dict) and set(data.keys()) <= _HARNESS_PROFILE_CONFIG_KEYS

Try / catch

try:
    config = HarnessProfileConfig.from_dict(data)
except TypeError as e:
    if "Unknown keys" in str(e):
        data = {k: v for k, v in data.items() if k in _HARNESS_PROFILE_CONFIG_KEYS}
        config = HarnessProfileConfig.from_dict(data)
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/158486dfb888f35a. Report an issue: GitHub.