langchain-ai/deepagents · error · ValueError

ConfigResolution must have at least one used path

Error message

ConfigResolution must have at least one used path

What it means

ConfigResolution's __post_init__ invariant requires at least one used path: an MCP config resolution must be backed by at least one config source. Constructing a ConfigResolution with an empty used_paths list fails this dataclass invariant with a ValueError.

Source

Thrown at libs/code/deepagents_code/mcp_login_service.py:159

    """Discovered config files that failed to parse or validate, `(path, error)`.

    Surfaced even on success: a broken project `.mcp.json` (or an approved
    server that fails per-server validation) can be dropped while another
    discovered config still loads. Reporting it here matches
    `resolve_and_load_mcp_tools`, which emits the same failures as
    `status="error"` rows rather than swallowing them. On `ConfigResolutionError`
    the reason is already embedded in `message`, so the field lives only here.
    See `format_load_errors_notice`."""

    def __post_init__(self) -> None:
        """Enforce the non-empty `used_paths` invariant.

        Raises:
            ValueError: If `used_paths` is empty.
        """
        if not self.used_paths:
            msg = "ConfigResolution must have at least one used path"
            raise ValueError(msg)

    @property
    def search_label(self) -> str:
        """Human-readable join of the paths backing this resolution."""
        return ", ".join(str(path) for path in self.used_paths)


@dataclass(frozen=True)
class ServerSelection:
    """Resolved server config plus enough context for error messages."""

    server_name: str
    """Selected MCP server name (matches an `mcpServers` key)."""

    server_config: McpServerSpec
    """Validated server config payload for `mcp_auth.login`."""

    search_label: str = ""

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Pass at least one path in used_paths — typically the global user config path that always participates in resolution.
  2. If no sources exist, create/point to a config file first rather than constructing an empty resolution.
  3. In tests, use the real resolver output or seed a temp config file instead of hand-building ConfigResolution.

Example fix

// before
ConfigResolution(value=servers, used_paths=[])
// after
ConfigResolution(value=servers, used_paths=[Path(user_config_path)])
Defensive patterns

Strategy: validation

Validate before calling

if not used_paths:
    raise ValueError("ConfigResolution needs at least one source path (e.g. the global user config)")

Try / catch

try:
    resolution = build_resolution(...)
except ValueError as exc:
    if "at least one used path" in str(exc):
        resolution = default_resolution_with_global_config()
    else:
        raise

Prevention

When it happens

Trigger: Programmatically constructing `ConfigResolution(...)` (e.g. in tests or custom tooling around resolve_mcp_config) passing `used_paths=[]`, or building one from a resolution pipeline that collected no paths.

Common situations: Test fixtures that build ConfigResolution objects manually and forget to include the fallback global config path; custom code that filters out all config sources before constructing the resolution.

Related errors


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