Skip to content

fix: read workspaceSearchPaths scoped per folder in multi-root workspaces#1448

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/fix-multi-root-workspace-settings
Draft

fix: read workspaceSearchPaths scoped per folder in multi-root workspaces#1448
Copilot wants to merge 4 commits intomainfrom
copilot/fix-multi-root-workspace-settings

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 9, 2026

In a multi-root workspace, python-envs.workspaceSearchPaths set in a folder's .vscode/settings.json was silently ignored. getWorkspaceSearchPaths() called getConfiguration('python-envs') without a scope URI, so inspect().workspaceFolderValue was always undefined — VS Code needs a folder URI to resolve per-folder settings.

Changes

  • getWorkspaceSearchPaths(scope?: Uri) — accepts an optional folder URI and passes it to getConfiguration, allowing VS Code to return the correct workspaceFolderValue per folder.

  • getAllExtraSearchPaths() — replaced the single unscoped call with a per-folder loop. Each workspace folder's paths are resolved relative to that specific folder, not broadcast against all folders.

// Before — one unscoped call; workspaceFolderValue always undefined in multi-root
const workspaceSearchPaths = getWorkspaceSearchPaths();
// relative paths then resolved against every workspace folder

// After — one call per folder, scope-aware
for (const folder of workspaceFolders) {
    const paths = getWorkspaceSearchPaths(folder.uri);   // scoped ✓
    workspaceSearchPathsPerFolder.push({ paths, folder: folder.uri });
}
// each relative path resolved only against the folder it came from
  • New unit tests — two multi-root scenarios: (1) verifies folder-specific configs are read independently via scoped calls, (2) verifies a relative path from folderA is not resolved against folderB.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh gh issue list --state open --limit 5 --json number,title,labels (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Problem

In a multi-root workspace, python-envs.workspaceSearchPaths configured in a folder's .vscode/settings.json is silently ignored. This is because getWorkspaceSearchPaths() in src/managers/common/nativePythonFinder.ts calls getConfiguration('python-envs') without passing a scope URI. In VS Code's API, when no scope is provided, inspect().workspaceFolderValue is undefined in multi-root workspaces — VS Code doesn't know which folder to inspect.

Fixes #1417

Root Cause

In src/managers/common/nativePythonFinder.ts:

  1. getWorkspaceSearchPaths() (around line 900) calls getConfiguration('python-envs') without a scope parameter. In a multi-root workspace, inspect('workspaceSearchPaths').workspaceFolderValue is always undefined because VS Code needs a folder URI to know which folder's settings to return.

  2. getAllExtraSearchPaths() (around line 824) calls getWorkspaceSearchPaths() only once (unscoped), then resolves relative paths against all workspace folders. This is incorrect for multi-root: if folderA configures ./envs and folderB configures ./venvs, you don't want ./envs resolved against folderB.

Required Fix

1. getWorkspaceSearchPaths() — add an optional scope parameter

Change the function signature to accept an optional Uri scope and pass it to getConfiguration:

function getWorkspaceSearchPaths(scope?: Uri): string[] {
    try {
        const envConfig = getConfiguration('python-envs', scope);  // ← pass scope
        const inspection = envConfig.inspect<string[]>('workspaceSearchPaths');
        // ... rest of function stays the same

2. getAllExtraSearchPaths() — iterate over workspace folders

Replace the current single unscoped call with a per-folder loop. Instead of:

const workspaceSearchPaths = getWorkspaceSearchPaths();

Do:

const workspaceFolders = getWorkspaceFolders();
const workspaceSearchPathsPerFolder: { paths: string[]; folder?: Uri }[] = [];

if (workspaceFolders && workspaceFolders.length > 0) {
    for (const folder of workspaceFolders) {
        const paths = getWorkspaceSearchPaths(folder.uri);
        workspaceSearchPathsPerFolder.push({ paths, folder: folder.uri });
    }
} else {
    // No workspace folders — fall back to unscoped
    workspaceSearchPathsPerFolder.push({ paths: getWorkspaceSearchPaths() });
}

// Resolve relative paths against the *specific* folder they came from
for (const { paths, folder } of workspaceSearchPathsPerFolder) {
    for (const searchPath of paths) {
        if (!searchPath || searchPath.trim() === '') continue;
        const trimmedPath = searchPath.trim();

        if (isAbsolutePath(trimmedPath)) {
            searchDirectories.push(trimmedPath);
        } else if (folder) {
            const resolvedPath = path.resolve(folder.fsPath, trimmedPath);
            searchDirectories.push(resolvedPath);
        } else {
            traceWarn('No workspace folder for relative search path:', trimmedPath);
        }
    }
}

3. Update the existing unit tests

The existing tests in src/test/managers/common/nativePythonFinder.getAllExtraSearchPaths.unit.test.ts mock getConfiguration without a scope. The tests that exercise workspaceFolderValue will need to be updated so that the mock returns the correct workspaceFolderValue when called with a specific folder URI scope. Make sure all existing tests still pass, and add a new test that verifies multi-root folder-level settings are read correctly (i.e., different folders returning different workspaceSearchPaths).

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: Tell me how to repro and debug this.

Assistant:

Let me investigate the issue and the codebase to understand how python-envs.workspaceSearchPaths is handled and why it might be silently ignored in multi-root workspaces.

Assistant: Now I have a thorough understanding of the code. Here's the root cause and how to repro/debug:


Root Cause

The bug is in getWorkspaceSearchPaths() at nativePythonFinder.ts lines 900–927. The function calls getConfiguration('python-envs') without passing a scope (i.e., no workspace-folder Uri):

function getWorkspaceSearchPaths(): string[] {
    try {
        const envConfig = getConfiguration('python-envs');  // ← no scope!
        const inspection = envConfig.inspect<string[]>('workspaceSearchPaths');
        // ...
        if (inspection?.workspaceFolderValue) ...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

Copilot AI changed the title [WIP] Fix ignored workspace search paths in multi-root workspaces fix: read workspaceSearchPaths scoped per folder in multi-root workspaces Apr 9, 2026
Copilot AI requested a review from edvilme April 9, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In multi-root workspaces, folder-level python-envs.workspaceSearchPaths is ignored silently

2 participants