langflow-ai/langflow · error · ValueError

Could not find valid Windows user directory in WSL

Error message

Could not find valid Windows user directory in WSL

What it means

Raised by get_config_path() in Langflow's MCP projects API when resolving the Claude Desktop config file from inside WSL. The code first tries to run Windows cmd.exe to discover the Windows username, then falls back to scanning /mnt/c/Users for the first non-system directory. If /mnt/c exists but /mnt/c/Users is missing or contains only filtered system directories (Default*, Public, All Users), no path can be derived and this ValueError is thrown.

Source

Thrown at src/backend/base/langflow/api/v1/mcp_projects.py:1279

                    # Fallback: try to find the Windows user directory
                    users_dir = Path("/mnt/c/Users")
                    if users_dir.exists():
                        # Get the first non-system user directory
                        user_dirs = [
                            d
                            for d in users_dir.iterdir()
                            if d.is_dir() and not d.name.startswith(("Default", "Public", "All Users"))
                        ]
                        if user_dirs:
                            return user_dirs[0] / "AppData" / "Roaming" / "Claude" / "claude_desktop_config.json"

                    if not Path("/mnt/c").exists():
                        msg = "Windows C: drive not mounted at /mnt/c in WSL"
                        raise ValueError(msg)

                    msg = "Could not find valid Windows user directory in WSL"
                    raise ValueError(msg)
                except (OSError, CalledProcessError) as e:
                    await logger.awarning("Failed to determine Windows user path in WSL: %s", str(e))
                    msg = f"Could not determine Windows Claude config path in WSL: {e!s}"
                    raise ValueError(msg) from e
            # Regular Windows
            return Path(os.environ["APPDATA"]) / "Claude" / "claude_desktop_config.json"

        msg = "Unsupported operating system for Claude configuration"
        raise ValueError(msg)

    msg = "Unsupported client"
    raise ValueError(msg)


def remove_server_by_urls(config_data: dict, urls: Sequence[str] | str) -> tuple[dict, list[str]]:
    """Remove any MCP servers that use one of the specified URLs from config data.

    Returns:

View on GitHub (pinned to 976ec789d2)

Solutions

  1. Verify /mnt/c/Users actually contains your Windows profile directory: ls /mnt/c/Users — if it is missing or only shows Default/Public, fix the WSL automount (check /etc/wsl.conf [automount] root setting) so C:\ mounts at /mnt/c.
  2. If your Windows user profile is on another drive or a custom mount point, create /mnt/c/Users/<yourname> visibility by mounting the real Windows drive at /mnt/c (sudo mount -t drvfs C: /mnt/c).
  3. Run Langflow on native Windows or macOS where the Claude config path resolves directly, or run it in a plain Linux environment and configure an MCP client that is supported there (cursor, windsurf).
  4. As a last resort, call the MCP config endpoints for a supported client, or patch get_config_path to accept an explicit path override via an environment variable (e.g. CLAUDE_CONFIG_PATH).

Example fix

# before: relies on /mnt/c/Users containing a real profile
# (raises 'Could not find valid Windows user directory in WSL')

# after: explicit override honored before WSL probing
def get_config_path(client: str) -> Path:
    if client.lower() == "claude":
        override = os.environ.get("CLAUDE_CONFIG_PATH")
        if override:
            return Path(override)
        ...
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
import platform

def wsl_claude_config_resolvable() -> bool:
    """Pre-check the WSL fallback conditions get_config_path('claude') needs."""
    if platform.system() != "Linux" or "microsoft" not in platform.uname().release.lower():
        return True  # not WSL; other code path applies
    users = Path("/mnt/c/Users")
    if not users.is_dir():
        return False
    return any(
        d.is_dir() and not d.name.startswith(("Default", "Public", "All Users"))
        for d in users.iterdir()
    )

Try / catch

try:
    path = await get_config_path("claude")
except ValueError as e:
    if "Windows user directory" in str(e) or "Windows Claude config path" in str(e):
        # fall back to asking the user for the config path explicitly
        path = Path(user_supplied_claude_config_path)
    else:
        raise

Prevention

When it happens

Trigger: Calling get_config_path("claude") on Linux where 'microsoft' appears in platform.uname().release (WSL), the cmd.exe subprocess fails or returns empty output, /mnt/c exists, and either /mnt/c/Users does not exist or every entry under it starts with 'Default', 'Public', or 'All Users'. Also hit on WSL distros that mount the Windows drive at a non-standard location while /mnt/c happens to exist but is empty.

Common situations: Running Langflow in WSL2 with the Windows drive auto-mounted under a different path (custom wsl.conf automount root), a hardened WSL setup where /mnt/c is an empty stub directory, a Windows install whose user profiles live on a non-C drive, or a fresh Windows profile state where only default/public directories exist under C:\Users.

Related errors


AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14). Data as JSON: /api/errors/748b32be0f5a3f99. Report an issue: GitHub.