langchain-ai/deepagents · error · ManagedConfigError

ManagedConfigError(ProviderStatus(name, path, ProviderHealth

Error message

ManagedConfigError(ProviderStatus(name, path, ProviderHealth.CORRUPT, reason))

What it means

When a config provider loads but returns an Invalid result, _raise_for_managed_provider raises ManagedConfigError with a ProviderStatus whose health is CORRUPT and whose reason comes from the Invalid result. This distinguishes 'file loaded but content is invalid' (353) from 'file could not be used at all' (352).

Source

Thrown at libs/code/deepagents_code/mcp_disabled.py:288

def _raise_for_managed_provider(
    provider: RankedProviderValue[list[str]],
) -> None:
    """Apply the deny-list callsite's fail-closed health policy.

    Raises:
        ManagedConfigError: If the provider is unhealthy or its value is invalid.
    """
    from deepagents_code.configuration.service import ManagedConfigError
    from deepagents_code.configuration.types import (
        Invalid,
        ProviderHealth,
        ProviderStatus,
    )

    if not provider.status.usable:
        raise ManagedConfigError(provider.status)
    if isinstance(provider.result, Invalid):
        raise ManagedConfigError(
            ProviderStatus(
                provider.status.name,
                provider.status.path,
                ProviderHealth.CORRUPT,
                provider.result.reason,
            )
        )


def _disabled_entries(data: dict[str, Any]) -> set[str]:
    """Return disabled names from the current config shape with legacy fallback."""
    section = data.get(_SECTION)
    if isinstance(section, dict):
        entries = _coerce_entries(section.get(_KEY))
        if entries is not None:
            return entries

    legacy_section = data.get(_LEGACY_SECTION)

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Read the `reason` in the raised ManagedConfigError — it names the validation failure.
  2. Open the config file at provider.status.path and fix the `disabled_servers` value to be a list of server-name strings.
  3. Remove the invalid key entirely to fall back to defaults, then re-add it correctly.
  4. Validate the file with a TOML/YAML linter before saving.

Example fix

# before
disabled_servers = "notion"
# after
disabled_servers = ["notion"]
Defensive patterns

Strategy: validation

Validate before calling

import tomllib
with open(config_path, "rb") as f:
    data = tomllib.load(f)
ds = data.get("disabled_servers", [])
assert isinstance(ds, list) and all(isinstance(x, str) for x in ds), "disabled_servers must be a list of strings"

Type guard

def is_list_of_str(value: object) -> TypeGuard[list[str]]:
    return isinstance(value, list) and all(isinstance(x, str) for x in value)

Try / catch

try:
    disabled = get_disabled_servers()
except ManagedConfigError as exc:
    print(f"corrupt config at {exc.status.path}: {exc.status.detail or ''}")

Prevention

When it happens

Trigger: Calling get_disabled_servers when a ranked provider returns result of type Invalid while its status is otherwise usable — i.e. the config file parsed far enough to be read but its content failed validation (e.g. `disabled_servers: "foo"` instead of a list of strings).

Common situations: Hand-editing `disabled_servers` to a string or dict instead of a list; schema drift after an upgrade changed the expected shape; partial writes leaving malformed TOML/YAML content.

Related errors


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