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
- Remove the scaffolding middleware classes/names from `HarnessProfile.excluded_middleware`.
- Use `excluded_tools` on the profile to hide individual tools (e.g. specific filesystem tools) instead of excluding whole middleware.
- 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
- Hide tools via `excluded_tools`, never by excluding scaffolding middleware.
- Keep a shared, reviewed profile factory instead of ad-hoc exclusions.
- Add a unit test that constructs your profile through `create_deep_agent`.
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
- HarnessProfile.excluded_middleware name entry matched multip
- HarnessProfile.excluded_middleware entries matched no middle
- `mode` must be one of 'thread', 'turn', or 'call'.
- {what} must be absolute: {path}
- Home directory is not absolute: {launch_home}. Set $HOME to
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/bc8583a1ef3d00b7.
Report an issue: GitHub.