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
- Pass at least one path in used_paths — typically the global user config path that always participates in resolution.
- If no sources exist, create/point to a config file first rather than constructing an empty resolution.
- 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
- Always include the global user config path in used_paths
- Prefer running the real resolver over hand-building ConfigResolution in tests
- Filter config sources before resolution, not after, so paths stay non-empty
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
- MCPServerInfo {self.name!r}: status='ok' cannot carry an err
- MCPServerInfo {self.name!r}: status={self.status!r} requires
- MCP config file not found: {mcp_config_path}
- Invalid MCP config at {mcp_config_path}: {exc}
- {prefix}.{name} must be a dictionary, got {type(values).__na
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/bfba2cbaedcf548c.
Report an issue: GitHub.