Skip to content

Incorrect IInspectValue property used instead of scalar value in scope detection #301471

Closed

Description

Bug

Two IConfigurationValue property accesses introduced in bb18007 use the IInspectValue<T> object property instead of the scalar value property, causing incorrect scope detection.

1. themeConfiguration.ts - findAutoConfigurationTarget()

Line 380 checks settings.userRemote instead of settings.userRemoteValue:

public findAutoConfigurationTarget(key: string) {
    const settings = this.configurationService.inspect(key);
    if (!types.isUndefined(settings.workspaceFolderValue)) {    // ✓ scalar
        return ConfigurationTarget.WORKSPACE_FOLDER;
    } else if (!types.isUndefined(settings.workspaceValue)) {   // ✓ scalar
        return ConfigurationTarget.WORKSPACE;
    } else if (!types.isUndefined(settings.userRemote)) {       // ✗ IInspectValue object
        return ConfigurationTarget.USER_REMOTE;
    }
    return ConfigurationTarget.USER;
}

settings.userRemote is an IInspectValue<T> object ({value?, override?, overrides?}). It can be defined when only language-specific overrides exist in the remote config, even if no actual remote value is set. This causes theme settings to incorrectly target USER_REMOTE scope.

2. commandLineAutoApprover.ts - source target detection

Line 282 checks configInspectValue.workspaceFolder instead of configInspectValue.workspaceFolderValue:

const sourceTarget = (
    checkTarget(configInspectValue.workspaceFolder) ? ConfigurationTarget.WORKSPACE_FOLDER
        : checkTarget(configInspectValue.workspaceValue) ? ConfigurationTarget.WORKSPACE
            : checkTarget(configInspectValue.userRemoteValue) ? ConfigurationTarget.USER_REMOTE
                ...
);

configInspectValue.workspaceFolder is an IInspectValue<T> whose keys are {value, override, overrides}. The checkTarget function looks for tool-pattern keys (e.g., "git*") via hasOwnProperty, which never matches on IInspectValue. This means workspace-folder-scoped auto-approve rules are never detected as such and fall through to a lower-priority scope.

Root Cause

Both are from the same commit (bb18007) and follow the same pattern: the IConfigurationValue<T> interface exposes both scalar values (e.g., userRemoteValue: T) and inspect objects (e.g., userRemote: IInspectValue<T>). The similar naming makes it easy to pick the wrong one.

Fix

  • settings.userRemote -> settings.userRemoteValue
  • configInspectValue.workspaceFolder -> configInspectValue.workspaceFolderValue

Activity

  1. khalidsaidi commented on Mar 14, 2026

    @khalidsaidi

    A2ABench has an accepted answer for this imported thread.

  2. sandy081 commented on Mar 18, 2026

    @sandy081
    Member

    Thank you for the detailed analysis! To help us investigate this further, could you provide specific steps to reproduce the issue? For example, a scenario where the configuration target is incorrectly detected — such as a setting unexpectedly targeting USER_REMOTE or a workspace-folder auto-approve rule not being recognized. While the code references are appreciated, having a concrete repro scenario would help us confirm the behavior and prioritize a fix. Thank you!

  3. ShehabSherif0 commented on Mar 19, 2026

    @ShehabSherif0
    ContributorAuthor

    Sandeep Somavarapu (@sandy081) Thank you for the quick response! Here are the detailed reproduction steps and the type-level analysis for both bugs.

    Bug 2: commandLineAutoApprover.ts (actively used, reproducible)

    Steps to reproduce:

    1. Open a multi-root workspace or any workspace with a folder
    2. In the folder's .vscode/settings.json, add:
      {
          "terminal.chat.agentTools.autoApprove": {
              "git*": true
          }
      }
    3. In the terminal chat, invoke a command matching git* (e.g., git status)
    4. Check the auto-approve rule's reported sourceTarget

    Expected: The matched rule's sourceTarget should be ConfigurationTarget.WORKSPACE_FOLDER, and the UI label should show "(workspace)".

    Actual: The sourceTarget falls through to a lower-priority scope because checkTarget(configInspectValue.workspaceFolder) passes the IInspectValue object (with shape {value?, override?, overrides?}) instead of the scalar config value.

    Why it fails:

    The checkTarget function does:

    function checkTarget(inspectValue: Readonly<unknown> | undefined): boolean {
        return (
            isObject(inspectValue) &&
            Object.prototype.hasOwnProperty.call(inspectValue, key) &&  // key = "git*"
            structuralEquals((inspectValue as Record<string, unknown>)[key], value)
        );
    }

    When called with configInspectValue.workspaceFolder (an IInspectValue), the object's own keys are {value, override, overrides}. So hasOwnProperty(obj, "git*") always returns false, and the workspace-folder scope is never matched.

    When called with configInspectValue.workspaceFolderValue (the scalar T), the object is {"git*": true}. So hasOwnProperty(obj, "git*") correctly returns true.

    Note: The remaining scopes in the same ternary chain (workspaceValue, userRemoteValue, userLocalValue, userValue, applicationValue) already use the correct *Value properties. Only workspaceFolder was wrong.

    Bug 1: themeConfiguration.ts (currently dead code, but still incorrect)

    findAutoConfigurationTarget currently has zero callers in the codebase, so this has no runtime impact today. However, the code is still wrong for the same reason: settings.userRemote is IInspectValue<T>, not the scalar T value. The toInspectValue() method in ConfigurationInspectValue (configurationModels.ts#L574) returns a defined object when any of value, override, or overrides exist:

    private toInspectValue(inspectValue: ...): IInspectValue<V> | undefined {
        return inspectValue?.value !== undefined 
            || inspectValue?.override !== undefined 
            || inspectValue?.overrides !== undefined ? inspectValue : undefined;
    }

    This means settings.userRemote can be non-undefined (e.g., because language-specific overrides exist in the remote config) while settings.userRemoteValue (the actual scalar value) is undefined. So checking !types.isUndefined(settings.userRemote) can incorrectly return true.

    Root cause

    Both are from commit bb18007 where these files were created as new files. The IConfigurationValue<T> interface exposes both scalar values (e.g., userRemoteValue: T) and inspect objects (e.g., userRemote: IInspectValue<T>). The similar naming makes it easy to pick the wrong one.

    The fix (in PR #301472)

    Both are single-property corrections:

    • configInspectValue.workspaceFolder -> configInspectValue.workspaceFolderValue
    • settings.userRemote -> settings.userRemoteValue

    The PR also includes a regression test that stubs configurationService.inspect() to return a workspaceFolderValue containing a rule key and asserts the matched rule reports sourceTarget as ConfigurationTarget.WORKSPACE_FOLDER.

  4. added
    bugIssue identified by VS Code Team member as probable bug
    terminalGeneral terminal issues that don't fall under another label
    and removed
    info-neededIssue requires more information from poster
    on Mar 19, 2026
  5. modified the milestone: on Mar 19, 2026
  6. 9 remaining items

  7. removed this from the 1.117.0 milestone on Apr 20, 2026
  8. gjsjohnmurray commented on May 5, 2026

    @gjsjohnmurray
    Contributor

    Case 2 looks similar to #301508. Alex Ross (@alexr00) when you removed this from the 1.117.0 milestone was it intentional that you didn't add it to another? I worry about it now being lost in space.

  9. alexr00 commented on May 5, 2026

    @alexr00
    Member

    John Murray (@gjsjohnmurray) as part of our weekly release process we ask team members to move their issues off of the milestone that we're releasing themselves. If they don't, then they risk losing their issues in space 🌠

  10. added
    insiders-releasedPatch has been released in VS Code Insiders
    and removed
    unreleasedPatch has not yet been released in VS Code Insiders
    on May 5, 2026
  11. locked and limited conversation to collaborators on Jun 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugIssue identified by VS Code Team member as probable buginsiders-releasedPatch has been released in VS Code InsidersterminalGeneral terminal issues that don't fall under another labelverifiedVerification succeeded

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions