langchain-ai/deepagents · error · ValueError

HarnessProfile.excluded_middleware is invalid: - required

Error message

HarnessProfile.excluded_middleware is invalid:
  - required scaffolding cannot be excluded: {', '.join(labels)} (back filesystem tools, subagent dispatch, and permission enforcement — use excluded_tools for per-tool visibility or adjust profile settings instead of stripping scaffolding)

What it means

HarnessProfileConfig.__post_init__ protects required agent scaffolding. Middleware listed in excluded_middleware that is identified by _scaffolding_violation_label as core (back filesystem tools, subagent dispatch, permission enforcement) triggers ValueError via _format_scaffolding_rejection, because removing it would break deepagents' core invariants. The message directs you to excluded_tools or profile settings instead.

Source

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

    is dropped too. Async subagents are unaffected.
    """

    def __post_init__(self) -> None:
        """Freeze mutable mappings and validate grammar of string entries."""
        if not isinstance(self.tool_description_overrides, MappingProxyType):
            object.__setattr__(
                self,
                "tool_description_overrides",
                MappingProxyType(dict(self.tool_description_overrides)),
            )
        scaffolding_violations: list[str] = []
        for entry in self.excluded_middleware:
            _validate_config_middleware_string(entry, "excluded_middleware")
            label = _scaffolding_violation_label(entry)
            if label is not None:
                scaffolding_violations.append(label)
        if scaffolding_violations:
            raise ValueError(_format_scaffolding_rejection(scaffolding_violations))

    def to_dict(self) -> dict[str, Any]:
        """Dump this config to plain dict/list/scalar values.

        Suitable for `json.dumps` or `yaml.safe_dump`. Fields at their
        default are omitted so the output stays minimal and round-trips
        cleanly through `from_dict`.

        Returns:
            A plain dict containing only the fields set on this config.

        Raises:
            TypeError: If `tool_description_overrides` contains a non-string
                key or value.
        """
        out: dict[str, Any] = {}
        if self.base_system_prompt is not None:
            out["base_system_prompt"] = self.base_system_prompt

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Remove the core middleware name from excluded_middleware.
  2. Use excluded_tools to hide specific tools instead of excluding whole middleware.
  3. Adjust profile settings (permissions mode, tool visibility) rather than stripping scaffolding.
  4. Check release notes if this config worked in an older deepagents version.

Example fix

// before
HarnessProfileConfig(name="thin", excluded_middleware=["filesystem_tools"])
// after
HarnessProfileConfig(name="thin", excluded_tools=["ls", "read_file"])
Defensive patterns

Strategy: try-catch

Validate before calling

SCAFFOLDING = {"filesystem_tools", "subagents", "permissions"}
bad = [m for m in getattr(cfg, "excluded_middleware", []) if m in SCAFFOLDING]
if bad:
    raise ValueError(f"cannot exclude scaffolding: {bad}")

Try / catch

try:
    config = HarnessProfileConfig(**raw)
except ValueError as e:
    if "excluded_middleware is invalid" in str(e):
        logging.error("%s — move to excluded_tools", e)
        raw.pop("excluded_middleware", None)
        config = HarnessProfileConfig(**raw)
    else:
        raise

Prevention

When it happens

Trigger: Constructing HarnessProfileConfig(...) with excluded_middleware containing core middleware names (e.g. filesystem-tools, subagents/Summarization-style dispatch, permissions/hitl middleware), whether in code or in a YAML/JSON profile file.

Common situations: Profile authors trying to slim the agent by stripping required middleware; copying an old config that excluded middleware now classified as scaffolding after a version change.

Related errors


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