{"record":{"id":"bc8583a1ef3d00b7","repo":"langchain-ai/deepagents","slug":"harnessprofile-excluded-middleware-is-invalid","errorCode":null,"errorMessage":"HarnessProfile.excluded_middleware is invalid:\n  - 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)","messagePattern":"HarnessProfile\\.excluded_middleware is invalid:\n  - required scaffolding cannot be excluded: (.+?) \\(back filesystem tools, subagent dispatch, and permission enforcement — use excluded_tools for per-tool visibility or adjust profile settings instead of stripping scaffolding\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/_excluded_middleware.py","lineNumber":64,"sourceCode":"    if not excluded:\n        return\n\n    excluded_classes: set[type[AgentMiddleware[Any, Any, Any]]] = set()\n    excluded_names: set[str] = set()\n    for entry in excluded:\n        if isinstance(entry, type):\n            excluded_classes.add(entry)\n        else:\n            excluded_names.add(entry)\n\n    forbidden_classes = excluded_classes & required_classes\n    forbidden_names = excluded_names & required_names\n    if forbidden_classes or forbidden_names:\n        # Lazy import: harness_profiles owns the per-class guidance text.\n        from deepagents.profiles.harness.harness_profiles import _format_scaffolding_rejection  # noqa: PLC0415\n\n        labels = [cls.__name__ for cls in forbidden_classes] + [f\"{name!r} (string)\" for name in forbidden_names]\n        raise ValueError(_format_scaffolding_rejection(labels))\n\n\ndef _raise_on_name_collisions(\n    name_matched_types: dict[str, set[type[AgentMiddleware[Any, Any, Any]]]],\n) -> None:\n    \"\"\"Raise `ValueError` if any string exclusion matched multiple distinct classes.\n\n    A string entry that drops instances of more than one concrete class is\n    almost always a surprise — e.g. a user middleware whose `.name`\n    accidentally collides with a built-in alias. Force the caller to use a\n    class-form exclusion via the runtime `HarnessProfile` to disambiguate.\n    \"\"\"\n    collisions = {name: classes for name, classes in name_matched_types.items() if len(classes) > 1}\n    if not collisions:\n        return\n    labels = sorted(f\"{name!r} matched {sorted(cls.__name__ for cls in classes)}\" for name, classes in collisions.items())\n    msg = (\n        \"HarnessProfile.excluded_middleware name entry matched multiple \"","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/_excluded_middleware.py#L46-L82","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nHarnessProfile(excluded_middleware=[FilesystemMiddleware, SubagentMiddleware])\n// after\nHarnessProfile(excluded_tools=[\"ls\", \"read_file\"], excluded_middleware=[MyOptionalMiddleware])","handlingStrategy":"validation","validationCode":"required = {\"back filesystem tools\", \"subagent\", \"permission\"}  # scaffolding names\nbad = [m for m in profile.excluded_middleware if name_of(m) in required]\nif bad:\n    raise ValueError(f\"cannot exclude scaffolding: {bad}\")  # fix before create_deep_agent","typeGuard":null,"tryCatchPattern":"try:\n    agent = create_deep_agent(profile=profile, ...)\nexcept ValueError as e:\n    if \"required scaffolding cannot be excluded\" in str(e):\n        profile = dataclasses.replace(profile, excluded_middleware=[m for m in profile.excluded_middleware if not is_scaffolding(m)])\n        agent = create_deep_agent(profile=profile, ...)\n    else:\n        raise","preventionTips":["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`."],"tags":["configuration","harness-profile","middleware","validation"],"backgroundTag":"required-scaffolding-exclusion","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}