langchain-ai/deepagents · error · ValueError

`{field_name}` entry {entry!r} cannot start with '_' (unders

Error message

`{field_name}` entry {entry!r} cannot start with '_' (underscore-prefixed names refer to private middleware classes not part of the public exclusion surface).

What it means

Middleware names starting with an underscore are reserved as private and cannot be referenced in config exclusion lists. Underscore-prefixed names map to private middleware classes that are not part of the public exclusion surface, so allowing them would create an unstable API contract.

Source

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

    """
    if not isinstance(entry, str):
        msg = f"`{field_name}` entries must be strings, got {type(entry).__name__} ({entry!r})"
        raise TypeError(msg)
    if not entry or entry.isspace():
        msg = f"`{field_name}` entries must be non-empty, non-whitespace strings"
        raise ValueError(msg)
    if ":" in entry:
        msg = (
            f"`{field_name}` entries must be plain middleware names; class-path (`module:Class`) entries are not currently supported, got {entry!r}."
        )
        raise ValueError(msg)
    if entry.startswith("_"):
        msg = (
            f"`{field_name}` entry {entry!r} cannot start with '_' "
            f"(underscore-prefixed names refer to private middleware classes "
            f"not part of the public exclusion surface)."
        )
        raise ValueError(msg)


def _serialize_runtime_excluded_middleware_entry(
    entry: type[AgentMiddleware] | str,
) -> str:
    """Serialize a runtime `excluded_middleware` entry back to config form.

    Class entries are only serializable when the class advertises a public
    `serialized_name` alias; arbitrary class-path serialization is not
    currently supported.
    """
    if isinstance(entry, str):
        return entry

    alias = getattr(entry, "serialized_name", None)
    if isinstance(alias, str) and alias:
        return alias

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Drop the leading underscore or use the corresponding public middleware name
  2. Look up the public alias of the middleware in the profile registry
  3. If you truly need to exclude a private middleware, do it in code via the class object rather than string config

Example fix

# before
config = HarnessProfileConfig(excluded_middleware=["_summarization"])
# after
config = HarnessProfileConfig(excluded_middleware=["summarization"])
Defensive patterns

Strategy: validation

Validate before calling

if any(n.startswith("_") for n in excluded_middleware):
    raise ValueError("private (_-prefixed) middleware names are not excludable")

Type guard

def is_public_middleware_name(entry: str) -> bool:
    return bool(entry) and not entry.startswith("_") and ":" not in entry

Try / catch

try:
    config = HarnessProfileConfig(excluded_middleware=entries)
except ValueError as e:
    if "cannot start with '_'" in str(e):
        entries = [n.lstrip("_") for n in entries]
        config = HarnessProfileConfig(excluded_middleware=entries)
    else:
        raise

Prevention

When it happens

Trigger: Passing an entry like `"_summarization"` in `excluded_middleware` (or another validated middleware string list) when constructing a HarnessProfileConfig.

Common situations: Reading library internals and copying a private class's name into config; assuming underscore names are addressable because they appear in source; typo'd names accidentally prefixed with `_`.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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