{"record":{"id":"06a768f2b59e7438","repo":"langchain-ai/deepagents","slug":"harnessprofile-excluded-middleware-name-entry-matc","errorCode":null,"errorMessage":"HarnessProfile.excluded_middleware name entry matched multiple distinct middleware classes within a single stack: {'; '.join(labels)}. Use a class-form exclusion via the runtime `HarnessProfile` to disambiguate.","messagePattern":"HarnessProfile\\.excluded_middleware name entry matched multiple distinct middleware classes within a single stack: (.+?)\\. Use a class-form exclusion via the runtime `HarnessProfile` to disambiguate\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/_excluded_middleware.py","lineNumber":87,"sourceCode":") -> 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 \"\n        \"distinct middleware classes within a single stack: \"\n        f\"{'; '.join(labels)}. Use a class-form exclusion via the runtime \"\n        \"`HarnessProfile` to disambiguate.\"\n    )\n    raise ValueError(msg)\n\n\ndef _apply_excluded_middleware(\n    stack: list[AgentMiddleware[Any, Any, Any]],\n    profile: HarnessProfile,\n    *,\n    matched_classes: set[type[AgentMiddleware[Any, Any, Any]]] | None = None,\n    matched_names: set[str] | None = None,\n) -> list[AgentMiddleware[Any, Any, Any]]:\n    \"\"\"Drop middleware in the stack matched by `profile.excluded_middleware`.\n\n    Class entries match on exact type (not `isinstance`), mirroring the\n    slot-identity semantics of `_merge_middleware` so a subclass introduced\n    by the caller is preserved when the profile excludes the base class.\n    String entries match `AgentMiddleware.name` exactly — defaults to the\n    class's `__name__` but is overridable when the public alias differs from\n    the impl class (e.g. `SummarizationMiddleware` for\n    `_DeepAgentsSummarizationMiddleware`).","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/_excluded_middleware.py#L69-L105","documentation":"When applying a `HarnessProfile`, a string entry in `excluded_middleware` matched more than one distinct middleware class within a single assembled stack, making the exclusion ambiguous. `_raise_on_name_collisions` raises `ValueError` and instructs the developer to use a class-form exclusion to disambiguate.","triggerScenarios":"`create_deep_agent`/`_apply_excluded_middleware` assembles stacks where two different middleware classes share a name referenced by a string entry in `profile.excluded_middleware` (e.g. two packages both exporting a class with the same short name, or the same name registered on multiple stacks).","commonSituations":"Using string names in profiles when multiple middleware providers define same-named classes; custom middleware named identically to a built-in; combining partner packages that both ship e.g. a `SummarizationMiddleware`.","solutions":["Replace the ambiguous string entry with the explicit middleware class in `excluded_middleware`.","Rename your custom middleware class so it no longer collides with the built-in name.","If both same-named middlewares are intended, scope exclusions per-stack rather than by bare name."],"exampleFix":"// before\nHarnessProfile(excluded_middleware=[\"SummarizationMiddleware\"])\n// after\nfrom my_stack import MySummarizationMiddleware\nHarnessProfile(excluded_middleware=[MySummarizationMiddleware])","handlingStrategy":"validation","validationCode":"from collections import Counter\nname_counts = Counter(m for m in profile.excluded_middleware if isinstance(m, str))\ndupes = [n for n, c in name_counts.items() if c > 1]\nif dupes:\n    raise ValueError(f\"ambiguous string exclusions: {dupes}\")","typeGuard":null,"tryCatchPattern":"try:\n    agent = create_deep_agent(profile=profile, ...)\nexcept ValueError as e:\n    if \"matched multiple distinct middleware classes\" in str(e):\n        profile = replace_strings_with_classes(profile)  # class-form exclusions\n        agent = create_deep_agent(profile=profile, ...)\n    else:\n        raise","preventionTips":["Prefer class-form exclusions over string names to eliminate ambiguity.","Avoid naming custom middleware after built-in middleware classes.","Keep middleware imports centralized so collisions are visible at import time."],"tags":["configuration","harness-profile","middleware","ambiguity"],"backgroundTag":"ambiguous-middleware-name","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}