git-ecosystem/git-credential-manager · error · InvalidOperationException

Must have a specific configuration level filter to modify…

Error message

Must have a specific configuration level filter to modify values.

What it means

GitConfiguration modification paths call EnsureSpecificLevel, which rejects GitConfigurationLevel.All: writing or modifying configuration requires a specific level (System, Global, Local, etc.) because git itself needs --system/--global/--local style scoping to know which file to change. Reading may use All, but writes cannot.

Solutions

  1. Pass an explicit level such as GitConfigurationLevel.Global or Local when modifying values.
  2. Map 'Any' semantics to a deliberate default (e.g. Global for user-wide settings) before writing.
  3. Guard call sites with a check that level != GitConfigurationLevel.All before invoking write APIs.

Example fix

// before
config.SetValue(Constants.GitConfiguration.Credential.SectionName, "helper", helper, GitConfigurationLevel.All);
// after
config.SetValue(Constants.GitConfiguration.Credential.SectionName, "helper", helper, GitConfigurationLevel.Global);
Defensive patterns

Strategy: validation

Validate before calling

if (level == GitConfigurationLevel.All)
    throw new InvalidOperationException("Writes require a specific configuration level (e.g. Global).");

Type guard

bool IsWritableLevel(GitConfigurationLevel level) => level != GitConfigurationLevel.All;

Try / catch

try
{
    config.SetValue(section, property, value, level);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("specific configuration level"))
{
    // retry with an explicit level such as GitConfigurationLevel.Global
}

Prevention

When it happens

Trigger: Calling a set/unset/modify API on GitProcessConfiguration with level == GitConfigurationLevel.All, e.g. config.SetValue(..., GitConfigurationLevel.All, ...) instead of naming the exact level to persist into.

Common situations: Developers reusing a level value read with All and passing it to a write; UI code defaulting to All; helper functions that accept a level parameter receiving All from generic call sites.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11). Data as JSON: /api/errors/03aff16659b5b52a. Report an issue: GitHub.

Appendix: source

Thrown at src/Core/GitConfiguration.cs:806

                switch (git.ExitCode)
                {
                    case 0: // OK
                    case 5: // Trying to unset a value that does not exist
                        InvalidateCache();
                        break;
                    default:
                        _trace.WriteLine($"Failed to unset all multivar '{name}' with value regex '{valueRegex}' (exit={git.ExitCode}, level={level})");
                        throw GitProcess.CreateGitException(git, $"Failed to unset all Git configuration multi-valued entries '{name}'");
                }
            }
        }

        private static void EnsureSpecificLevel(GitConfigurationLevel level)
        {
            if (level == GitConfigurationLevel.All)
            {
                throw new InvalidOperationException("Must have a specific configuration level filter to modify values.");
            }
        }

        private static string GetLevelFilterArg(GitConfigurationLevel level)
        {
            switch (level)
            {
                case GitConfigurationLevel.System:
                    return "--system";
                case GitConfigurationLevel.Global:
                    return "--global";
                case GitConfigurationLevel.Local:
                    return "--local";
                case GitConfigurationLevel.Unknown:
                default:
                    return null;
            }
        }

View on GitHub (pinned to e8ce762cd0)