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

`create_deep_agent` validates a `HarnessProfile`'s `excluded_middleware` list and rejects any exclusion that targets required scaffolding middleware (back filesystem tools, subagent dispatch, permission enforcement). Stripping those breaks core agent invariants, so `_validate_excluded_middleware_config` raises `ValueError` listing the offending classes/names with guidance to use `excluded_tools` instead.

Source

Thrown at libs/deepagents/deepagents/_excluded_middleware.py:64

    if not excluded:
        return

    excluded_classes: set[type[AgentMiddleware[Any, Any, Any]]] = set()
    excluded_names: set[str] = set()
    for entry in excluded:
        if isinstance(entry, type):
            excluded_classes.add(entry)
        else:
            excluded_names.add(entry)

    forbidden_classes = excluded_classes & required_classes
    forbidden_names = excluded_names & required_names
    if forbidden_classes or forbidden_names:
        # Lazy import: harness_profiles owns the per-class guidance text.
        from deepagents.profiles.harness.harness_profiles import _format_scaffolding_rejection  # noqa: PLC0415

        labels = [cls.__name__ for cls in forbidden_classes] + [f"{name!r} (string)" for name in forbidden_names]
        raise ValueError(_format_scaffolding_rejection(labels))


def _raise_on_name_collisions(
    name_matched_types: dict[str, set[type[AgentMiddleware[Any, Any, Any]]]],
) -> None:
    """Raise `ValueError` if any string exclusion matched multiple distinct classes.

    A string entry that drops instances of more than one concrete class is
    almost always a surprise — e.g. a user middleware whose `.name`
    accidentally collides with a built-in alias. Force the caller to use a
    class-form exclusion via the runtime `HarnessProfile` to disambiguate.
    """
    collisions = {name: classes for name, classes in name_matched_types.items() if len(classes) > 1}
    if not collisions:
        return
    labels = sorted(f"{name!r} matched {sorted(cls.__name__ for cls in classes)}" for name, classes in collisions.items())
    msg = (
        "HarnessProfile.excluded_middleware name entry matched multiple "

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Remove the scaffolding middleware classes/names from `HarnessProfile.excluded_middleware`.
  2. Use `excluded_tools` on the profile to hide individual tools (e.g. specific filesystem tools) instead of excluding whole middleware.
  3. Adjust other profile settings (permissions, tool visibility) to achieve the intent without stripping scaffolding.

Example fix

// before
HarnessProfile(excluded_middleware=[FilesystemMiddleware, SubagentMiddleware])
// after
HarnessProfile(excluded_tools=["ls", "read_file"], excluded_middleware=[MyOptionalMiddleware])
Defensive patterns

Strategy: validation

Validate before calling

required = {"back filesystem tools", "subagent", "permission"}  # scaffolding names
bad = [m for m in profile.excluded_middleware if name_of(m) in required]
if bad:
    raise ValueError(f"cannot exclude scaffolding: {bad}")  # fix before create_deep_agent

Try / catch

try:
    agent = create_deep_agent(profile=profile, ...)
except ValueError as e:
    if "required scaffolding cannot be excluded" in str(e):
        profile = dataclasses.replace(profile, excluded_middleware=[m for m in profile.excluded_middleware if not is_scaffolding(m)])
        agent = create_deep_agent(profile=profile, ...)
    else:
        raise

Prevention

When it happens

Trigger: Passing a `HarnessProfile` to `create_deep_agent` whose `excluded_middleware` contains (by class or string name) one of the required middleware classes — e.g. the filesystem tools middleware, subagent middleware, or permissions middleware.

Common situations: Trying to hide all tools by excluding whole middleware instead of individual tools; copying a profile from an older version where a class was excludable; typos that accidentally collide with a scaffolding name.

Related errors


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